diff --git a/configs/csfb.yaml.in b/configs/csfb.yaml.in
index 9538a580e..53f19af8d 100644
--- a/configs/csfb.yaml.in
+++ b/configs/csfb.yaml.in
@@ -59,7 +59,7 @@ mme:
smf:
- address: 127.0.0.4
sgsap:
- server:
+ client:
- address: 127.0.0.2
map:
tai:
diff --git a/configs/open5gs/amf.yaml.in b/configs/open5gs/amf.yaml.in
index 24e2c9757..3919c5c2c 100644
--- a/configs/open5gs/amf.yaml.in
+++ b/configs/open5gs/amf.yaml.in
@@ -59,43 +59,83 @@ amf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-amf.svc.local
# sbi:
# server:
# - dev:eth0
# advertise: open5gs-amf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: amf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.5 and advertise as open5gs-amf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.5
+# port: 7777
+# advertise: open5gs-amf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.5
+# port: 7777
+# advertise: open5gs-amf.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -117,6 +157,27 @@ amf:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/amf.key
+# cert: @sysconfdir@/open5gs/tls/amf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/amf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/amf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: amf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/ausf.yaml.in b/configs/open5gs/ausf.yaml.in
index db4c79f57..52291fdf7 100644
--- a/configs/open5gs/ausf.yaml.in
+++ b/configs/open5gs/ausf.yaml.in
@@ -22,43 +22,83 @@ ausf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-ausf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-ausf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: ausf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.11 and advertise as open5gs-ausf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.11
+# port: 7777
+# advertise: open5gs-ausf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.11
+# port: 7777
+# advertise: open5gs-ausf.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -80,6 +120,27 @@ ausf:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/ausf.key
+# cert: @sysconfdir@/open5gs/tls/ausf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/ausf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/ausf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: ausf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/bsf.yaml.in b/configs/open5gs/bsf.yaml.in
index 37ceced21..12bc11433 100644
--- a/configs/open5gs/bsf.yaml.in
+++ b/configs/open5gs/bsf.yaml.in
@@ -22,43 +22,83 @@ bsf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-bsf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-bsf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: bsf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.15 and advertise as open5gs-bsf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.15
+# port: 7777
+# advertise: open5gs-bsf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.15
+# port: 7777
+# advertise: open5gs-bsf.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -80,6 +120,27 @@ bsf:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/bsf.key
+# cert: @sysconfdir@/open5gs/tls/bsf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/bsf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/bsf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: bsf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/mme.yaml.in b/configs/open5gs/mme.yaml.in
index b3daf838d..39b2a0071 100644
--- a/configs/open5gs/mme.yaml.in
+++ b/configs/open5gs/mme.yaml.in
@@ -164,8 +164,9 @@ mme:
################################################################################
# o MSC/VLR
# sgsap:
-# server:
-# - address: 127.0.0.2
+# client:
+# - address: msc.open5gs.org # SCTP server address configured on the MSC/VLR
+# local_address: 127.0.0.2 # SCTP local IP addresses to be bound in the MME
# map:
# tai:
# plmn_id:
@@ -188,7 +189,15 @@ mme:
# mcc: 002
# mnc: 02
# lac: 43692
-# - address: msc.open5gs.org
+# - address: # SCTP server address configured on the MSC/VLR
+# - 127.0.0.88
+# - 10.0.0.88
+# - 172.16.0.88
+# - 2001:db8:babe::88
+# local_address: # SCTP local IP addresses to be bound in the MME
+# - 127.0.0.2
+# - 192.168.1.4
+# - 2001:db8:cafe::2
# map:
# tai:
# plmn_id:
diff --git a/configs/open5gs/nrf.yaml.in b/configs/open5gs/nrf.yaml.in
index e082c0fb8..c69f8c40c 100644
--- a/configs/open5gs/nrf.yaml.in
+++ b/configs/open5gs/nrf.yaml.in
@@ -21,18 +21,31 @@ nrf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-nrf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-nrf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: nrf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.10 and advertise as open5gs-nrf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.10
+# port: 7777
+# advertise: open5gs-nrf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.10
+# port: 7777
+# advertise: open5gs-nrf.svc.local:8888
#
################################################################################
# HTTPS scheme with TLS
@@ -51,6 +64,24 @@ nrf:
# server:
# - address: nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/nrf.key
+# cert: @sysconfdir@/open5gs/tls/nrf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/nrf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/nrf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/nssf.yaml.in b/configs/open5gs/nssf.yaml.in
index 258ff7825..015085f56 100644
--- a/configs/open5gs/nssf.yaml.in
+++ b/configs/open5gs/nssf.yaml.in
@@ -25,18 +25,31 @@ nssf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-nssf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-nssf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: nssf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.14 and advertise as open5gs-nssf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.14
+# port: 7777
+# advertise: open5gs-nssf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.14
+# port: 7777
+# advertise: open5gs-nssf.svc.local:8888
#
################################################################################
# SBI Client
@@ -64,27 +77,55 @@ nssf:
# sst: 1
# sd: 009000
#
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
+#
#
################################################################################
# HTTPS scheme with TLS
@@ -110,6 +151,31 @@ nssf:
# s_nssai:
# sst: 1
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/nssf.key
+# cert: @sysconfdir@/open5gs/tls/nssf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/nssf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/nssf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: nssf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+# nsi:
+# - uri: https://nrf.localdomain
+# s_nssai:
+# sst: 1
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/pcf.yaml.in b/configs/open5gs/pcf.yaml.in
index afe96458b..10fd43faf 100644
--- a/configs/open5gs/pcf.yaml.in
+++ b/configs/open5gs/pcf.yaml.in
@@ -148,43 +148,83 @@ pcf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-pcf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-pcf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: pcf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.13 and advertise as open5gs-pcf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.13
+# port: 7777
+# advertise: open5gs-pcf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.13
+# port: 7777
+# advertise: open5gs-pcf.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -206,6 +246,27 @@ pcf:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/pcf.key
+# cert: @sysconfdir@/open5gs/tls/pcf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/pcf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/pcf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: pcf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/scp.yaml.in b/configs/open5gs/scp.yaml.in
index 3d80497eb..b2d4795d0 100644
--- a/configs/open5gs/scp.yaml.in
+++ b/configs/open5gs/scp.yaml.in
@@ -63,28 +63,78 @@ scp:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-scp.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-scp.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: scp.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.200 and advertise as open5gs-scp.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.200
+# port: 7777
+# advertise: open5gs-scp.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.200
+# port: 7777
+# advertise: open5gs-scp.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
+# o Indirect Communication by Delegating to Next-SCP
+# sbi:
+# client:
+# scp:
+# - uri: http://127.0.0.200:7777
+#
+# o Indirect Communication without Delegation
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegation
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the Next-SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
+#
################################################################################
# HTTPS scheme with TLS
################################################################################
@@ -105,6 +155,27 @@ scp:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/scp.key
+# cert: @sysconfdir@/open5gs/tls/scp.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/scp-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/scp-client-sslkeylog.log
+# sbi:
+# server:
+# - address: scp.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/sepp1.yaml.in b/configs/open5gs/sepp1.yaml.in
index afa276a35..46d774ca5 100644
--- a/configs/open5gs/sepp1.yaml.in
+++ b/configs/open5gs/sepp1.yaml.in
@@ -148,6 +148,36 @@ sepp:
# uri: https://sepp2.localdomain
# resolve: 127.0.2.251
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# private_key: @sysconfdir@/open5gs/tls/sepp1.key
+# cert: @sysconfdir@/open5gs/tls/sepp1.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp1-server-sslkeylog.log
+# client:
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp1-client-sslkeylog.log
+# sbi:
+# server:
+# - address: 127.0.1.250
+# port: 7777
+# client:
+# scp:
+# - uri: http://127.0.0.200:7777
+# n32:
+# server:
+# - sender: sepp1.localdomain
+# scheme: https
+# address: 127.0.1.251
+# client:
+# sepp:
+# - receiver: sepp2.localdomain
+# uri: https://sepp2.localdomain
+# resolve: 127.0.2.251
+#
# o Add client TLS verification to N32 interface
# default:
# tls:
diff --git a/configs/open5gs/sepp2.yaml.in b/configs/open5gs/sepp2.yaml.in
index fc78fb256..2b67f3f35 100644
--- a/configs/open5gs/sepp2.yaml.in
+++ b/configs/open5gs/sepp2.yaml.in
@@ -14,8 +14,10 @@ sepp:
server:
private_key: @sysconfdir@/open5gs/tls/sepp2.key
cert: @sysconfdir@/open5gs/tls/sepp2.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp2-server-sslkeylog.log
client:
cacert: @sysconfdir@/open5gs/tls/ca.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp2-client-sslkeylog.log
sbi:
server:
- address: 127.0.2.250
@@ -148,6 +150,36 @@ sepp:
# uri: https://sepp1.localdomain
# resolve: 127.0.1.251
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# private_key: @sysconfdir@/open5gs/tls/sepp2.key
+# cert: @sysconfdir@/open5gs/tls/sepp2.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp2-server-sslkeylog.log
+# client:
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/sepp2-client-sslkeylog.log
+# sbi:
+# server:
+# - address: 127.0.2.250
+# port: 7777
+# client:
+# scp:
+# - uri: http://127.0.0.200:7777
+# n32:
+# server:
+# - sender: sepp2.localdomain
+# scheme: https
+# address: 127.0.2.251
+# client:
+# sepp:
+# - receiver: sepp1.localdomain
+# uri: https://sepp1.localdomain
+# resolve: 127.0.1.251
+#
# o Add client TLS verification to N32 interface
# default:
# tls:
diff --git a/configs/open5gs/smf.yaml.in b/configs/open5gs/smf.yaml.in
index 3ec2fb648..e47752393 100644
--- a/configs/open5gs/smf.yaml.in
+++ b/configs/open5gs/smf.yaml.in
@@ -186,43 +186,83 @@ smf:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-smf.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-smf.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: smf.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.4 and advertise as open5gs-smf.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.4
+# port: 7777
+# advertise: open5gs-smf.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.4
+# port: 7777
+# advertise: open5gs-smf.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -244,6 +284,27 @@ smf:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/smf.key
+# cert: @sysconfdir@/open5gs/tls/smf.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/smf-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/smf-client-sslkeylog.log
+# sbi:
+# server:
+# - address: smf.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/udm.yaml.in b/configs/open5gs/udm.yaml.in
index a6a718094..395d041f6 100644
--- a/configs/open5gs/udm.yaml.in
+++ b/configs/open5gs/udm.yaml.in
@@ -38,7 +38,6 @@ udm:
scp:
- uri: http://127.0.0.200:7777
-#
################################################################################
# Home Network Public Key
################################################################################
@@ -82,43 +81,83 @@ udm:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-udm.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-udm.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: udm.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.12 and advertise as open5gs-udm.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.12
+# port: 7777
+# advertise: open5gs-udm.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.12
+# port: 7777
+# advertise: open5gs-udm.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -140,6 +179,27 @@ udm:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/udm.key
+# cert: @sysconfdir@/open5gs/tls/udm.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/udm-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/udm-client-sslkeylog.log
+# sbi:
+# server:
+# - address: udm.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/open5gs/udr.yaml.in b/configs/open5gs/udr.yaml.in
index f8fd4250c..cfc41286c 100644
--- a/configs/open5gs/udr.yaml.in
+++ b/configs/open5gs/udr.yaml.in
@@ -23,43 +23,83 @@ udr:
################################################################################
# SBI Server
################################################################################
-# o Override SBI address to be advertised to NRF
+# o Bind to the address on the eth0 and advertise as open5gs-udr.svc.local
# sbi:
# server:
-# - dev: eth0
+# - dev:eth0
# advertise: open5gs-udr.svc.local
#
+# o Specify a custom port number 7777 while binding to the given address
# sbi:
# server:
-# - address: localhost
-# advertise:
-# - 127.0.0.99
-# - ::1
+# - address: udr.localdomain
+# port: 7777
+#
+# o Bind to 127.0.0.20 and advertise as open5gs-udr.svc.local
+# sbi:
+# server:
+# - address: 127.0.0.20
+# port: 7777
+# advertise: open5gs-udr.svc.local
+#
+# o Bind to port 7777 but advertise with a different port number 8888
+# sbi:
+# server:
+# - address: 127.0.0.20
+# port: 7777
+# advertise: open5gs-udr.svc.local:8888
#
################################################################################
# SBI Client
################################################################################
-# o Direct communication with NRF interaction
+# o Direct Communication with NRF
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
#
-# o Indirect communication with delegated discovery
+# o Indirect Communication by Delegating to SCP
# sbi:
# client:
# scp:
# - uri: http://127.0.0.200:7777
#
-# o Indirect communication without delegated discovery
+# o Indirect Communication without Delegation
# sbi:
# client:
# nrf:
# - uri: http://127.0.0.10:7777
# scp:
# - uri: http://127.0.0.200:7777
-# discovery:
-# delegated: no
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: no # Directly communicate NRF discovery
+# scp:
+# next: no # Do not delegate to SCP for next-hop
+#
+# o Indirect Communication with Delegated Discovery
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# delegated:
+# nrf:
+# nfm: no # Directly communicate NRF management functions
+# disc: yes # Delegate discovery to SCP
+# scp:
+# next: yes # Delegate to SCP for next-hop communications
+#
+# o Default delegation: all communications are delegated to the SCP
+# sbi:
+# client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+# scp:
+# - uri: http://127.0.0.200:7777
+# # No 'delegated' section; defaults to AUTO delegation
#
################################################################################
# HTTPS scheme with TLS
@@ -81,6 +121,27 @@ udr:
# nrf:
# - uri: https://nrf.localdomain
#
+# o Enable SSL key logging for Wireshark
+# - This configuration allows capturing SSL/TLS session keys
+# for debugging or analysis purposes using Wireshark.
+# default:
+# tls:
+# server:
+# scheme: https
+# private_key: @sysconfdir@/open5gs/tls/udr.key
+# cert: @sysconfdir@/open5gs/tls/udr.crt
+# sslkeylogfile: @localstatedir@/log/open5gs/tls/udr-server-sslkeylog.log
+# client:
+# scheme: https
+# cacert: @sysconfdir@/open5gs/tls/ca.crt
+# client_sslkeylogfile: @localstatedir@/log/open5gs/tls/udr-client-sslkeylog.log
+# sbi:
+# server:
+# - address: udr.localdomain
+# client:
+# nrf:
+# - uri: https://nrf.localdomain
+#
# o Add client TLS verification
# default:
# tls:
diff --git a/configs/srsenb.yaml.in b/configs/srsenb.yaml.in
index a30bbf520..9f2185dcd 100644
--- a/configs/srsenb.yaml.in
+++ b/configs/srsenb.yaml.in
@@ -67,7 +67,7 @@ mme:
tai:
- plmn_id:
mcc: 901
- mnc: 70
+ mnc: 70
tac: 7
security:
integrity_order : [ EIA2, EIA1, EIA0 ]
diff --git a/debian/control b/debian/control
index 8cb84efbd..d8c28b9ea 100644
--- a/debian/control
+++ b/debian/control
@@ -13,7 +13,7 @@ Build-Depends: debhelper (>= 11),
libgnutls28-dev,
libgcrypt-dev,
libssl-dev,
- libidn11-dev,
+ libidn-dev | libidn11-dev,
libmongoc-dev,
libbson-dev,
libsctp-dev,
diff --git a/debian/open5gs-common.dirs b/debian/open5gs-common.dirs
index d5b197ccf..be7656f72 100644
--- a/debian/open5gs-common.dirs
+++ b/debian/open5gs-common.dirs
@@ -1 +1 @@
-var/log/open5gs
+var/log/open5gs/tls
diff --git a/docker/debian/latest/base/Dockerfile b/docker/debian/latest/base/Dockerfile
index 072628d16..bac24f0b5 100644
--- a/docker/debian/latest/base/Dockerfile
+++ b/docker/debian/latest/base/Dockerfile
@@ -22,7 +22,6 @@ RUN apt-get update && \
libgnutls28-dev \
libgcrypt-dev \
libssl-dev \
- libidn11-dev \
libmongoc-dev \
libbson-dev \
libyaml-dev \
@@ -35,4 +34,9 @@ RUN apt-get update && \
ca-certificates \
netbase \
pkg-config && \
- apt-get clean
+ if apt-cache show libidn-dev > /dev/null 2>&1; then \
+ apt-get install -y --no-install-recommends libidn-dev; \
+ else \
+ apt-get install -y --no-install-recommends libidn11-dev; \
+ fi && \
+ apt-get clean && rm -rf /var/lib/apt/lists/*
diff --git a/docker/ubuntu/latest/base/Dockerfile b/docker/ubuntu/latest/base/Dockerfile
index 072628d16..bac24f0b5 100644
--- a/docker/ubuntu/latest/base/Dockerfile
+++ b/docker/ubuntu/latest/base/Dockerfile
@@ -22,7 +22,6 @@ RUN apt-get update && \
libgnutls28-dev \
libgcrypt-dev \
libssl-dev \
- libidn11-dev \
libmongoc-dev \
libbson-dev \
libyaml-dev \
@@ -35,4 +34,9 @@ RUN apt-get update && \
ca-certificates \
netbase \
pkg-config && \
- apt-get clean
+ if apt-cache show libidn-dev > /dev/null 2>&1; then \
+ apt-get install -y --no-install-recommends libidn-dev; \
+ else \
+ apt-get install -y --no-install-recommends libidn11-dev; \
+ fi && \
+ apt-get clean && rm -rf /var/lib/apt/lists/*
diff --git a/docs/_docs/guide/02-building-open5gs-from-sources.md b/docs/_docs/guide/02-building-open5gs-from-sources.md
index e22fdc7a5..01e572f6e 100644
--- a/docs/_docs/guide/02-building-open5gs-from-sources.md
+++ b/docs/_docs/guide/02-building-open5gs-from-sources.md
@@ -61,7 +61,7 @@ $ sudo ip link set ogstun up
Install the dependencies for building the source code.
```bash
-$ sudo apt install python3-pip python3-setuptools python3-wheel ninja-build build-essential flex bison git cmake libsctp-dev libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev libnghttp2-dev libmicrohttpd-dev libcurl4-gnutls-dev libnghttp2-dev libtins-dev libtalloc-dev meson
+$ sudo apt install python3-pip python3-setuptools python3-wheel ninja-build build-essential flex bison git cmake libsctp-dev libgnutls28-dev libgcrypt-dev libssl-dev libidn-dev libmongoc-dev libbson-dev libyaml-dev libnghttp2-dev libmicrohttpd-dev libcurl4-gnutls-dev libnghttp2-dev libtins-dev libtalloc-dev meson
```
Git clone.
@@ -447,7 +447,7 @@ $ cp open5gs* /usr/bin/
For convenience, you can execute all NFs at once by using the following command.
```bash
$ ./build/tests/app/5gc ## 5G Core Only with ./build/configs/sample.yaml
-$ ./build/tests/app/epc -c ./build/configs/srslte.yaml ## EPC Only with ./build/configs/srslte.yaml
+$ ./build/tests/app/epc -c ./build/configs/srsenb.yaml ## EPC Only with ./build/configs/srsenb.yaml
$ ./build/tests/app/app ## Both 5G Core and EPC with ./build/configs/sample.yaml
```
diff --git a/docs/_docs/troubleshoot/02-now-in-github-issues.md b/docs/_docs/troubleshoot/02-now-in-github-issues.md
index 06b26c352..11b1b84fc 100644
--- a/docs/_docs/troubleshoot/02-now-in-github-issues.md
+++ b/docs/_docs/troubleshoot/02-now-in-github-issues.md
@@ -1356,7 +1356,7 @@ $ DIST=debian TAG=stretch docker-compose run dev
```bash
$ sudo dpkg --add-architecture armel
$ sudo apt update
-$ sudo apt install libsctp-dev:armel libyaml-dev:armel libgnutls28-dev:armel libgcrypt-dev:armel libidn11-dev:armel libssl-dev:armel libmongoc-dev:armel libbson-dev:armel
+$ sudo apt install libsctp-dev:armel libyaml-dev:armel libgnutls28-dev:armel libgcrypt-dev:armel libidn-dev:armel libssl-dev:armel libmongoc-dev:armel libbson-dev:armel
$ sudo apt install crossbuild-essential-armel
$ sudo apt install qemu
$ git clone https://github.com/{{ site.github_username }}/open5gs
diff --git a/docs/_pages/docs.md b/docs/_pages/docs.md
index 350ef50ff..65d3b364a 100644
--- a/docs/_pages/docs.md
+++ b/docs/_pages/docs.md
@@ -20,7 +20,7 @@ head_inline: ""
- In the lab
- [A Demonstration of 30 Gbps Load Testing for Accelerated UPF with Open5gs](https://nextepc.com/technology)
- - [Measurement of UPF Performance](https://github.com/s5uishida/simple_measurement_of_upf_performance)
+ - [Measurement of UPF Performance](https://github.com/s5uishida/sample_config_misc_for_mobile_network#performance_measurement)
- Troubleshooting
- [Simple Issues](troubleshoot/01-simple-issues)
@@ -43,6 +43,7 @@ head_inline: ""
- [SMF Code Explanation](https://medium.com/@aditya.koranga/open5gs-smf-code-explanation-with-flow-charts-a3b3cd38c991)
- @infinitydon
+ - [OAI's O-RAN Integration With Open5gs 5G Core](https://futuredon.medium.com/integrating-disaggregated-openairinterface-o-ran-components-with-open5gs-5g-core-76e5deac1730)
- [Open5GS on Amazon Elastic Kubernetes Service](https://aws.amazon.com/blogs/opensource/open-source-mobile-core-network-implementation-on-amazon-elastic-kubernetes-service/)
- [Kubernetes Open5GS Deployment](https://dev.to/infinitydon/virtual-4g-simulation-using-kubernetes-and-gns3-3b7k?fbclid=IwAR1p99h13a-mCfejanbBQe0H0-jp5grXkn5mWf1WrTHf47UtegB2-UHGGZQ)
- [5G Core SBI mTLS Using External Certificate PKI](https://futuredon.medium.com/5g-core-sbi-mtls-using-external-certificate-pki-4ffc02ac7728)
diff --git a/lib/app/ogs-config.c b/lib/app/ogs-config.c
index 01cfa1eb2..395712c80 100644
--- a/lib/app/ogs-config.c
+++ b/lib/app/ogs-config.c
@@ -247,6 +247,12 @@ int ogs_app_parse_global_conf(ogs_yaml_iter_t *parent)
} else if (!strcmp(parameter_key, "use_openair")) {
global_conf.parameter.use_openair =
ogs_yaml_iter_bool(¶meter_iter);
+ } else if (!strcmp(parameter_key, "use_upg_vpp")) {
+ global_conf.parameter.use_upg_vpp =
+ ogs_yaml_iter_bool(¶meter_iter);
+ } else if (!strcmp(parameter_key, "fake_csfb")) {
+ global_conf.parameter.fake_csfb =
+ ogs_yaml_iter_bool(¶meter_iter);
} else if (!strcmp(parameter_key,
"no_ipv4v6_local_addr_in_packet_filter")) {
global_conf.parameter.
@@ -1252,7 +1258,6 @@ ogs_app_slice_conf_t *ogs_app_slice_conf_add(
ogs_assert(policy_conf);
ogs_assert(s_nssai);
- ogs_assert(s_nssai->sst);
ogs_pool_alloc(&slice_conf_pool, &slice_conf);
if (!slice_conf) {
@@ -1283,7 +1288,6 @@ ogs_app_slice_conf_t *ogs_app_slice_conf_find_by_s_nssai(
ogs_assert(policy_conf);
ogs_assert(s_nssai);
- ogs_assert(s_nssai->sst);
ogs_list_for_each(&policy_conf->slice_list, slice_conf) {
if (slice_conf->data.s_nssai.sst == s_nssai->sst &&
diff --git a/lib/app/ogs-config.h b/lib/app/ogs-config.h
index 2086d9b98..6f98a7c66 100644
--- a/lib/app/ogs-config.h
+++ b/lib/app/ogs-config.h
@@ -69,6 +69,8 @@ typedef struct ogs_global_conf_s {
int multicast;
int use_openair;
+ int fake_csfb;
+ int use_upg_vpp;
int no_ipv4v6_local_addr_in_packet_filter;
int no_pfcp_rr_select;
diff --git a/lib/core/ogs-sockaddr.c b/lib/core/ogs-sockaddr.c
index fb8dbeb8c..61ad459db 100644
--- a/lib/core/ogs-sockaddr.c
+++ b/lib/core/ogs-sockaddr.c
@@ -55,6 +55,10 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
+static bool ogs_sockaddr_compare(const ogs_sockaddr_t *a,
+ const ogs_sockaddr_t *b,
+ bool compare_port);
+
/* If you want to use getnameinfo,
* you need to consider DNS query delay (about 10 seconds) */
#if 0
@@ -264,6 +268,60 @@ int ogs_sortaddrinfo(ogs_sockaddr_t **sa_list, int family)
return OGS_OK;
}
+/*--------------------------------------------------------------------------
+ * Merge a single node if not already in "dest" list
+ *--------------------------------------------------------------------------
+ */
+void ogs_merge_single_addrinfo(
+ ogs_sockaddr_t **dest, const ogs_sockaddr_t *item)
+{
+ ogs_sockaddr_t *p;
+ ogs_sockaddr_t *new_sa;
+
+ ogs_assert(dest);
+ ogs_assert(item);
+
+ p = *dest;
+
+ while (p) {
+ if (ogs_sockaddr_is_equal(p, item)) {
+ /* Already exists */
+ return;
+ }
+ p = p->next;
+ }
+ new_sa = (ogs_sockaddr_t *)ogs_malloc(sizeof(*new_sa));
+ ogs_assert(new_sa);
+ memcpy(new_sa, item, sizeof(*new_sa));
+ if (item->hostname) {
+ new_sa->hostname = ogs_strdup(item->hostname);
+ ogs_assert(new_sa->hostname);
+ }
+ new_sa->next = NULL;
+ if (!(*dest)) {
+ *dest = new_sa;
+ } else {
+ p = *dest;
+ while (p->next)
+ p = p->next;
+ p->next = new_sa;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Merge an entire src list into dest
+ *--------------------------------------------------------------------------
+ */
+void ogs_merge_addrinfo(ogs_sockaddr_t **dest, const ogs_sockaddr_t *src)
+{
+ const ogs_sockaddr_t *cur;
+ cur = src;
+ while (cur) {
+ ogs_merge_single_addrinfo(dest, cur);
+ cur = cur->next;
+ }
+}
+
ogs_sockaddr_t *ogs_link_local_addr(const char *dev, const ogs_sockaddr_t *sa)
{
#if defined(HAVE_GETIFADDRS)
@@ -419,13 +477,16 @@ socklen_t ogs_sockaddr_len(const void *sa)
}
}
-bool ogs_sockaddr_is_equal(const void *p, const void *q)
+/*
+ * Helper function to compare two addresses.
+ * If compare_port is true, compare both port and address.
+ * Otherwise, compare address only.
+ */
+static bool ogs_sockaddr_compare(const ogs_sockaddr_t *a,
+ const ogs_sockaddr_t *b,
+ bool compare_port)
{
- const ogs_sockaddr_t *a, *b;
-
- a = p;
ogs_assert(a);
- b = q;
ogs_assert(b);
if (a->ogs_sa_family != b->ogs_sa_family)
@@ -433,23 +494,68 @@ bool ogs_sockaddr_is_equal(const void *p, const void *q)
switch (a->ogs_sa_family) {
case AF_INET:
- if (a->sin.sin_port != b->sin.sin_port)
+ if (compare_port && (a->sin.sin_port != b->sin.sin_port))
return false;
- if (memcmp(&a->sin.sin_addr, &b->sin.sin_addr, sizeof(struct in_addr)) != 0)
+ if (memcmp(&a->sin.sin_addr, &b->sin.sin_addr,
+ sizeof(struct in_addr)) != 0)
return false;
return true;
case AF_INET6:
- if (a->sin6.sin6_port != b->sin6.sin6_port)
+ if (compare_port && (a->sin6.sin6_port != b->sin6.sin6_port))
return false;
- if (memcmp(&a->sin6.sin6_addr, &b->sin6.sin6_addr, sizeof(struct in6_addr)) != 0)
+ if (memcmp(&a->sin6.sin6_addr, &b->sin6.sin6_addr,
+ sizeof(struct in6_addr)) != 0)
return false;
return true;
default:
- ogs_error("Unexpected address faimily %u", a->ogs_sa_family);
+ ogs_error("Unexpected address family %u", a->ogs_sa_family);
ogs_abort();
+ return false; /* Defensive return */
}
}
+/* Compare addresses including port */
+bool ogs_sockaddr_is_equal(const void *p, const void *q)
+{
+ const ogs_sockaddr_t *a = (const ogs_sockaddr_t *)p;
+ const ogs_sockaddr_t *b = (const ogs_sockaddr_t *)q;
+ return ogs_sockaddr_compare(a, b, true);
+}
+
+/* Compare addresses without considering port */
+bool ogs_sockaddr_is_equal_addr(const void *p, const void *q)
+{
+ const ogs_sockaddr_t *a = (const ogs_sockaddr_t *)p;
+ const ogs_sockaddr_t *b = (const ogs_sockaddr_t *)q;
+ return ogs_sockaddr_compare(a, b, false);
+}
+
+bool ogs_sockaddr_check_any_match(
+ ogs_sockaddr_t *base,
+ ogs_sockaddr_t *list, const ogs_sockaddr_t *single, bool compare_port)
+{
+ ogs_sockaddr_t *p = NULL;
+
+ while (list) {
+ p = base;
+ while (p) {
+ if (ogs_sockaddr_compare(p, list, compare_port) == true)
+ return true;
+ p = p->next;
+ }
+ list = list->next;
+ }
+ if (single) {
+ p = base;
+ while (p) {
+ if (ogs_sockaddr_compare(p, single, compare_port) == true)
+ return true;
+ p = p->next;
+ }
+ }
+ return false;
+}
+
static int parse_network(ogs_ipsubnet_t *ipsub, const char *network)
{
/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
@@ -666,3 +772,31 @@ char *ogs_ipstrdup(ogs_sockaddr_t *addr)
return ogs_strdup(buf);
}
+
+char *ogs_sockaddr_to_string_static(ogs_sockaddr_t *sa_list)
+{
+ static char dumpstr[OGS_HUGE_LEN] = { 0, };
+ char *p, *last;
+ ogs_sockaddr_t *addr = NULL;
+
+ last = dumpstr + OGS_HUGE_LEN;
+ p = dumpstr;
+
+ addr = (ogs_sockaddr_t *)sa_list;
+ while (addr) {
+ char buf[OGS_ADDRSTRLEN];
+ p = ogs_slprintf(p, last, "[%s]:%d ",
+ OGS_ADDR(addr, buf), OGS_PORT(addr));
+ addr = addr->next;
+ }
+
+ if (p > dumpstr) {
+ /* If there is more than one addr, remove the last character */
+ *(p-1) = 0;
+
+ return dumpstr;
+ }
+
+ /* No address */
+ return NULL;
+}
diff --git a/lib/core/ogs-sockaddr.h b/lib/core/ogs-sockaddr.h
index a28e5b570..144255926 100644
--- a/lib/core/ogs-sockaddr.h
+++ b/lib/core/ogs-sockaddr.h
@@ -67,20 +67,8 @@ struct ogs_sockaddr_s {
* If there is a name in the configuration file,
* it is set in the 'hostname' of ogs_sockaddr_t.
* Then, it immediately call getaddrinfo() to fill addr in ogs_sockaddr_t.
- *
- * When it was always possible to convert DNS to addr, that was no problem.
- * However, in some environments, such as Roaming, there are situations
- * where it is difficult to always change the DNS to addr.
- *
- * So, 'fqdn' was created for the purpose of first use in ogs_sbi_client_t.
- * 'fqdn' always do not change with addr.
- * This value is used as it is in the actual client connection.
- *
- * Note that 'hostname' is still in use for server or other client
- * except for ogs_sbi_client_t.
*/
char *hostname;
- char *fqdn;
ogs_sockaddr_t *next;
};
@@ -103,6 +91,10 @@ int ogs_copyaddrinfo(
int ogs_filteraddrinfo(ogs_sockaddr_t **sa_list, int family);
int ogs_sortaddrinfo(ogs_sockaddr_t **sa_list, int family);
+void ogs_merge_single_addrinfo(
+ ogs_sockaddr_t **dest, const ogs_sockaddr_t *item);
+void ogs_merge_addrinfo(ogs_sockaddr_t **dest, const ogs_sockaddr_t *src);
+
ogs_sockaddr_t *ogs_link_local_addr(const char *dev, const ogs_sockaddr_t *sa);
ogs_sockaddr_t *ogs_link_local_addr_by_dev(const char *dev);
ogs_sockaddr_t *ogs_link_local_addr_by_sa(const ogs_sockaddr_t *sa);
@@ -119,12 +111,18 @@ int ogs_inet_pton(int family, const char *src, void *sa);
socklen_t ogs_sockaddr_len(const void *sa);
bool ogs_sockaddr_is_equal(const void *p, const void *q);
+bool ogs_sockaddr_is_equal_addr(const void *p, const void *q);
+
+bool ogs_sockaddr_check_any_match(
+ ogs_sockaddr_t *base,
+ ogs_sockaddr_t *list, const ogs_sockaddr_t *single, bool compare_port);
int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
const char *ipstr, const char *mask_or_numbits);
char *ogs_gethostname(ogs_sockaddr_t *addr);
char *ogs_ipstrdup(ogs_sockaddr_t *addr);
+char *ogs_sockaddr_to_string_static(ogs_sockaddr_t *sa_list);
#ifdef __cplusplus
}
diff --git a/lib/dbi/session.c b/lib/dbi/session.c
index ee1fa5f6a..5ebc7822d 100644
--- a/lib/dbi/session.c
+++ b/lib/dbi/session.c
@@ -85,6 +85,7 @@ int ogs_dbi_session_data(char *supi, ogs_s_nssai_t *s_nssai, char *dnn,
if (!strcmp(key, OGS_SLICE_STRING) && BSON_ITER_HOLDS_ARRAY(&iter)) {
bson_iter_recurse(&iter, &child1_iter);
while (bson_iter_next(&child1_iter)) {
+ bool sst_presence = false;
uint8_t sst;
ogs_uint24_t sd;
@@ -97,6 +98,7 @@ int ogs_dbi_session_data(char *supi, ogs_s_nssai_t *s_nssai, char *dnn,
if (!strcmp(child2_key, OGS_SST_STRING) &&
BSON_ITER_HOLDS_INT32(&child2_iter)) {
+ sst_presence = true;
sst = bson_iter_int32(&child2_iter);
} else if (!strcmp(child2_key, OGS_SD_STRING) &&
BSON_ITER_HOLDS_UTF8(&child2_iter)) {
@@ -109,7 +111,7 @@ int ogs_dbi_session_data(char *supi, ogs_s_nssai_t *s_nssai, char *dnn,
}
}
- if (!sst) {
+ if (!sst_presence) {
ogs_error("No SST");
continue;
}
diff --git a/lib/dbi/subscription.c b/lib/dbi/subscription.c
index 0f5ed89f2..6799a0c56 100644
--- a/lib/dbi/subscription.c
+++ b/lib/dbi/subscription.c
@@ -39,9 +39,16 @@ int ogs_dbi_auth_info(char *supi, ogs_dbi_auth_info_t *auth_info)
ogs_assert(auth_info);
supi_type = ogs_id_get_type(supi);
- ogs_assert(supi_type);
+ if (!supi_type) {
+ ogs_error("Invalid supi=%s", supi);
+ return OGS_ERROR;
+ }
supi_id = ogs_id_get_value(supi);
- ogs_assert(supi_id);
+ if (!supi_id) {
+ ogs_error("Invalid supi=%s", supi);
+ ogs_free(supi_type);
+ return OGS_ERROR;
+ }
query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
#if MONGOC_CHECK_VERSION(1, 5, 0)
@@ -459,6 +466,7 @@ int ogs_dbi_subscription_data(char *supi,
bson_iter_recurse(&iter, &child1_iter);
while (bson_iter_next(&child1_iter)) {
ogs_slice_data_t *slice_data = NULL;
+ bool sst_presence = false;
ogs_assert(
subscription_data->num_of_slice < OGS_MAX_NUM_OF_SLICE);
@@ -476,6 +484,7 @@ int ogs_dbi_subscription_data(char *supi,
if (!strcmp(child2_key, OGS_SST_STRING) &&
BSON_ITER_HOLDS_INT32(&child2_iter)) {
slice_data->s_nssai.sst = bson_iter_int32(&child2_iter);
+ sst_presence = true;
} else if (!strcmp(child2_key, OGS_SD_STRING) &&
BSON_ITER_HOLDS_UTF8(&child2_iter)) {
utf8 = bson_iter_utf8(&child2_iter, &length);
@@ -792,6 +801,12 @@ int ogs_dbi_subscription_data(char *supi,
}
}
}
+
+ if (!sst_presence) {
+ ogs_error("No SST");
+ continue;
+ }
+
subscription_data->num_of_slice++;
}
} else if (!strcmp(key, OGS_MME_HOST_STRING) &&
diff --git a/lib/diameter/common/base.h b/lib/diameter/common/base.h
index a44dece72..d8ad7f77a 100644
--- a/lib/diameter/common/base.h
+++ b/lib/diameter/common/base.h
@@ -90,7 +90,7 @@ int ogs_diam_start(void);
void ogs_diam_final(void);
int ogs_diam_config_init(ogs_diam_config_t *fd_config);
-bool ogs_diam_app_connected(uint32_t app_id);
+bool ogs_diam_is_relay_or_app_advertised(uint32_t app_id);
int fd_avp_search_avp ( struct avp * groupedavp,
struct dict_object * what, struct avp ** avp );
diff --git a/lib/diameter/common/util.c b/lib/diameter/common/util.c
index fa534c4b8..94a7fb8ee 100644
--- a/lib/diameter/common/util.c
+++ b/lib/diameter/common/util.c
@@ -19,7 +19,7 @@
#include "ogs-diameter-common.h"
-bool ogs_diam_app_connected(uint32_t app_id)
+bool ogs_diam_is_relay_or_app_advertised(uint32_t app_id)
{
struct fd_list *li = NULL;
struct fd_app *found = NULL;
@@ -36,18 +36,23 @@ bool ogs_diam_app_connected(uint32_t app_id)
if (state == STATE_OPEN) {
ogs_debug("'%s' STATE is OPEN", p->info.pi_diamid);
- /* Check if the remote peer advertised the message's appli */
- fd_app_check(&p->info.runtime.pir_apps, app_id, &found);
-
- if (found) break;
+ if (p->info.runtime.pir_relay) {
+ ogs_debug("'%s' RELAY is enabled", p->info.pi_diamid);
+ CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
+ return true;
+ } else {
+ /* Check if the remote peer advertised the message's appli */
+ fd_app_check(&p->info.runtime.pir_apps, app_id, &found);
+ if (found) {
+ CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
+ return true;
+ }
+ }
} else {
ogs_debug("'%s' STATE[%d] is NOT open ", p->info.pi_diamid, state);
}
}
CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
- if (found)
- return true;
- else
- return false;
+ return false;
}
diff --git a/lib/gtp/context.c b/lib/gtp/context.c
index 17620b4da..5c144b54f 100644
--- a/lib/gtp/context.c
+++ b/lib/gtp/context.c
@@ -200,6 +200,7 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
server_key);
}
+ /* Add address information */
addr = NULL;
for (i = 0; i < num; i++) {
rv = ogs_addaddrinfo(&addr,
@@ -207,17 +208,30 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
ogs_assert(rv == OGS_OK);
}
+ /* Add each address as a separate socknode */
if (addr) {
- if (ogs_global_conf()->parameter.
- no_ipv4 == 0)
- ogs_socknode_add(
- &self.gtpc_list, AF_INET, addr,
- is_option ? &option : NULL);
- if (ogs_global_conf()->parameter.
- no_ipv6 == 0)
- ogs_socknode_add(
- &self.gtpc_list6, AF_INET6, addr,
- is_option ? &option : NULL);
+ ogs_sockaddr_t *current = addr;
+ while (current) {
+ if (current->ogs_sa_family ==
+ AF_INET &&
+ ogs_global_conf()->
+ parameter.no_ipv4 == 0) {
+ ogs_socknode_add(&self.gtpc_list,
+ AF_INET, current,
+ is_option ?
+ &option : NULL);
+ }
+ if (current->ogs_sa_family ==
+ AF_INET6 &&
+ ogs_global_conf()->
+ parameter.no_ipv6 == 0) {
+ ogs_socknode_add(&self.gtpc_list6,
+ AF_INET6, current,
+ is_option ?
+ &option : NULL);
+ }
+ current = current->next;
+ }
ogs_freeaddrinfo(addr);
}
@@ -417,16 +431,28 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
ogs_list_init(&list6);
if (addr) {
- if (ogs_global_conf()->parameter.
- no_ipv4 == 0)
- ogs_socknode_add(
- &list, AF_INET, addr,
- is_option ? &option : NULL);
- if (ogs_global_conf()->parameter.
- no_ipv6 == 0)
- ogs_socknode_add(
- &list6, AF_INET6, addr,
- is_option ? &option : NULL);
+ ogs_sockaddr_t *current = addr;
+ while (current) {
+ if (current->ogs_sa_family ==
+ AF_INET &&
+ ogs_global_conf()->
+ parameter.no_ipv4 == 0) {
+ ogs_socknode_add(&list,
+ AF_INET, current,
+ is_option ?
+ &option : NULL);
+ }
+ if (current->ogs_sa_family ==
+ AF_INET6 &&
+ ogs_global_conf()->
+ parameter.no_ipv6 == 0) {
+ ogs_socknode_add(&list6,
+ AF_INET6, current,
+ is_option ?
+ &option : NULL);
+ }
+ current = current->next;
+ }
ogs_freeaddrinfo(addr);
}
diff --git a/lib/nas/5gs/ies.c b/lib/nas/5gs/ies.c
index 79d78117e..5c39a9eff 100644
--- a/lib/nas/5gs/ies.c
+++ b/lib/nas/5gs/ies.c
@@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.2.0
* Please do not modify this file but regenerate it via script.
- * Created on: 2024-01-21 18:47:47.812038 by acetcom
+ * Created on: 2024-12-11 21:13:08.097860 by acetcom
* from 24501-h90.docx
******************************************************************************/
@@ -48,7 +48,14 @@ int ogs_nas_5gs_encode_optional_type(ogs_pkbuf_t *pkbuf, uint8_t type)
int ogs_nas_5gs_decode_additional_information(ogs_nas_additional_information_t *additional_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_additional_information_t *source = (ogs_nas_additional_information_t *)pkbuf->data;
+ ogs_nas_additional_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_additional_information_t *)pkbuf->data;
additional_information->length = source->length;
size = additional_information->length + sizeof(additional_information->length);
@@ -87,7 +94,14 @@ int ogs_nas_5gs_encode_additional_information(ogs_pkbuf_t *pkbuf, ogs_nas_additi
int ogs_nas_5gs_decode_service_level_aa_container(ogs_nas_service_level_aa_container_t *service_level_aa_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_service_level_aa_container_t *source = (ogs_nas_service_level_aa_container_t *)pkbuf->data;
+ ogs_nas_service_level_aa_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_service_level_aa_container_t *)pkbuf->data;
service_level_aa_container->length = be16toh(source->length);
size = service_level_aa_container->length + sizeof(service_level_aa_container->length);
@@ -167,7 +181,14 @@ int ogs_nas_5gs_encode_access_type(ogs_pkbuf_t *pkbuf, ogs_nas_access_type_t *ac
int ogs_nas_5gs_decode_dnn(ogs_nas_dnn_t *dnn, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_dnn_t *source = (ogs_nas_dnn_t *)pkbuf->data;
+ ogs_nas_dnn_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_dnn_t *)pkbuf->data;
dnn->length = source->length;
size = dnn->length + sizeof(dnn->length);
@@ -219,7 +240,14 @@ int ogs_nas_5gs_encode_dnn(ogs_pkbuf_t *pkbuf, ogs_nas_dnn_t *dnn)
int ogs_nas_5gs_decode_eap_message(ogs_nas_eap_message_t *eap_message, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eap_message_t *source = (ogs_nas_eap_message_t *)pkbuf->data;
+ ogs_nas_eap_message_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eap_message_t *)pkbuf->data;
eap_message->length = be16toh(source->length);
size = eap_message->length + sizeof(eap_message->length);
@@ -299,7 +327,14 @@ int ogs_nas_5gs_encode_gprs_timer(ogs_pkbuf_t *pkbuf, ogs_nas_gprs_timer_t *gprs
int ogs_nas_5gs_decode_gprs_timer_2(ogs_nas_gprs_timer_2_t *gprs_timer_2, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_gprs_timer_2_t *source = (ogs_nas_gprs_timer_2_t *)pkbuf->data;
+ ogs_nas_gprs_timer_2_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_gprs_timer_2_t *)pkbuf->data;
gprs_timer_2->length = source->length;
size = gprs_timer_2->length + sizeof(gprs_timer_2->length);
@@ -338,7 +373,14 @@ int ogs_nas_5gs_encode_gprs_timer_2(ogs_pkbuf_t *pkbuf, ogs_nas_gprs_timer_2_t *
int ogs_nas_5gs_decode_gprs_timer_3(ogs_nas_gprs_timer_3_t *gprs_timer_3, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_gprs_timer_3_t *source = (ogs_nas_gprs_timer_3_t *)pkbuf->data;
+ ogs_nas_gprs_timer_3_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_gprs_timer_3_t *)pkbuf->data;
gprs_timer_3->length = source->length;
size = gprs_timer_3->length + sizeof(gprs_timer_3->length);
@@ -377,7 +419,14 @@ int ogs_nas_5gs_encode_gprs_timer_3(ogs_pkbuf_t *pkbuf, ogs_nas_gprs_timer_3_t *
int ogs_nas_5gs_decode_s_nssai(ogs_nas_s_nssai_t *s_nssai, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_s_nssai_t *source = (ogs_nas_s_nssai_t *)pkbuf->data;
+ ogs_nas_s_nssai_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_s_nssai_t *)pkbuf->data;
s_nssai->length = source->length;
size = s_nssai->length + sizeof(s_nssai->length);
@@ -416,7 +465,14 @@ int ogs_nas_5gs_encode_s_nssai(ogs_pkbuf_t *pkbuf, ogs_nas_s_nssai_t *s_nssai)
int ogs_nas_5gs_decode_5gmm_capability(ogs_nas_5gmm_capability_t *gmm_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gmm_capability_t *source = (ogs_nas_5gmm_capability_t *)pkbuf->data;
+ ogs_nas_5gmm_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gmm_capability_t *)pkbuf->data;
gmm_capability->length = source->length;
size = gmm_capability->length + sizeof(gmm_capability->length);
@@ -455,7 +511,14 @@ int ogs_nas_5gs_encode_5gmm_capability(ogs_pkbuf_t *pkbuf, ogs_nas_5gmm_capabili
int ogs_nas_5gs_decode_abba(ogs_nas_abba_t *abba, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_abba_t *source = (ogs_nas_abba_t *)pkbuf->data;
+ ogs_nas_abba_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_abba_t *)pkbuf->data;
abba->length = source->length;
size = abba->length + sizeof(abba->length);
@@ -494,7 +557,14 @@ int ogs_nas_5gs_encode_abba(ogs_pkbuf_t *pkbuf, ogs_nas_abba_t *abba)
int ogs_nas_5gs_decode_additional_5g_security_information(ogs_nas_additional_5g_security_information_t *additional_security_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_additional_5g_security_information_t *source = (ogs_nas_additional_5g_security_information_t *)pkbuf->data;
+ ogs_nas_additional_5g_security_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_additional_5g_security_information_t *)pkbuf->data;
additional_security_information->length = source->length;
size = additional_security_information->length + sizeof(additional_security_information->length);
@@ -533,7 +603,14 @@ int ogs_nas_5gs_encode_additional_5g_security_information(ogs_pkbuf_t *pkbuf, og
int ogs_nas_5gs_decode_additional_information_requested(ogs_nas_additional_information_requested_t *additional_information_requested, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_additional_information_requested_t *source = (ogs_nas_additional_information_requested_t *)pkbuf->data;
+ ogs_nas_additional_information_requested_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_additional_information_requested_t *)pkbuf->data;
additional_information_requested->length = source->length;
size = additional_information_requested->length + sizeof(additional_information_requested->length);
@@ -572,7 +649,14 @@ int ogs_nas_5gs_encode_additional_information_requested(ogs_pkbuf_t *pkbuf, ogs_
int ogs_nas_5gs_decode_allowed_pdu_session_status(ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_allowed_pdu_session_status_t *source = (ogs_nas_allowed_pdu_session_status_t *)pkbuf->data;
+ ogs_nas_allowed_pdu_session_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_allowed_pdu_session_status_t *)pkbuf->data;
allowed_pdu_session_status->length = source->length;
size = allowed_pdu_session_status->length + sizeof(allowed_pdu_session_status->length);
@@ -615,7 +699,14 @@ int ogs_nas_5gs_encode_allowed_pdu_session_status(ogs_pkbuf_t *pkbuf, ogs_nas_al
int ogs_nas_5gs_decode_authentication_failure_parameter(ogs_nas_authentication_failure_parameter_t *authentication_failure_parameter, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_failure_parameter_t *source = (ogs_nas_authentication_failure_parameter_t *)pkbuf->data;
+ ogs_nas_authentication_failure_parameter_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_failure_parameter_t *)pkbuf->data;
authentication_failure_parameter->length = source->length;
size = authentication_failure_parameter->length + sizeof(authentication_failure_parameter->length);
@@ -654,7 +745,14 @@ int ogs_nas_5gs_encode_authentication_failure_parameter(ogs_pkbuf_t *pkbuf, ogs_
int ogs_nas_5gs_decode_authentication_parameter_autn(ogs_nas_authentication_parameter_autn_t *authentication_parameter_autn, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_parameter_autn_t *source = (ogs_nas_authentication_parameter_autn_t *)pkbuf->data;
+ ogs_nas_authentication_parameter_autn_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_parameter_autn_t *)pkbuf->data;
authentication_parameter_autn->length = source->length;
size = authentication_parameter_autn->length + sizeof(authentication_parameter_autn->length);
@@ -727,7 +825,14 @@ int ogs_nas_5gs_encode_authentication_parameter_rand(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_5gs_decode_authentication_response_parameter(ogs_nas_authentication_response_parameter_t *authentication_response_parameter, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_response_parameter_t *source = (ogs_nas_authentication_response_parameter_t *)pkbuf->data;
+ ogs_nas_authentication_response_parameter_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_response_parameter_t *)pkbuf->data;
authentication_response_parameter->length = source->length;
size = authentication_response_parameter->length + sizeof(authentication_response_parameter->length);
@@ -798,7 +903,14 @@ int ogs_nas_5gs_encode_configuration_update_indication(ogs_pkbuf_t *pkbuf, ogs_n
int ogs_nas_5gs_decode_cag_information_list(ogs_nas_cag_information_list_t *cag_information_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_cag_information_list_t *source = (ogs_nas_cag_information_list_t *)pkbuf->data;
+ ogs_nas_cag_information_list_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_cag_information_list_t *)pkbuf->data;
cag_information_list->length = be16toh(source->length);
size = cag_information_list->length + sizeof(cag_information_list->length);
@@ -844,7 +956,14 @@ int ogs_nas_5gs_encode_cag_information_list(ogs_pkbuf_t *pkbuf, ogs_nas_cag_info
int ogs_nas_5gs_decode_ciphering_key_data(ogs_nas_ciphering_key_data_t *ciphering_key_data, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ciphering_key_data_t *source = (ogs_nas_ciphering_key_data_t *)pkbuf->data;
+ ogs_nas_ciphering_key_data_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ciphering_key_data_t *)pkbuf->data;
ciphering_key_data->length = be16toh(source->length);
size = ciphering_key_data->length + sizeof(ciphering_key_data->length);
@@ -890,7 +1009,14 @@ int ogs_nas_5gs_encode_ciphering_key_data(ogs_pkbuf_t *pkbuf, ogs_nas_ciphering_
int ogs_nas_5gs_decode_daylight_saving_time(ogs_nas_daylight_saving_time_t *daylight_saving_time, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_daylight_saving_time_t *source = (ogs_nas_daylight_saving_time_t *)pkbuf->data;
+ ogs_nas_daylight_saving_time_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_daylight_saving_time_t *)pkbuf->data;
daylight_saving_time->length = source->length;
size = daylight_saving_time->length + sizeof(daylight_saving_time->length);
@@ -997,7 +1123,14 @@ int ogs_nas_5gs_encode_de_registration_type(ogs_pkbuf_t *pkbuf, ogs_nas_de_regis
int ogs_nas_5gs_decode_emergency_number_list(ogs_nas_emergency_number_list_t *emergency_number_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_emergency_number_list_t *source = (ogs_nas_emergency_number_list_t *)pkbuf->data;
+ ogs_nas_emergency_number_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_emergency_number_list_t *)pkbuf->data;
emergency_number_list->length = source->length;
size = emergency_number_list->length + sizeof(emergency_number_list->length);
@@ -1036,7 +1169,14 @@ int ogs_nas_5gs_encode_emergency_number_list(ogs_pkbuf_t *pkbuf, ogs_nas_emergen
int ogs_nas_5gs_decode_eps_bearer_context_status(ogs_nas_eps_bearer_context_status_t *eps_bearer_context_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_bearer_context_status_t *source = (ogs_nas_eps_bearer_context_status_t *)pkbuf->data;
+ ogs_nas_eps_bearer_context_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_bearer_context_status_t *)pkbuf->data;
eps_bearer_context_status->length = source->length;
size = eps_bearer_context_status->length + sizeof(eps_bearer_context_status->length);
@@ -1075,7 +1215,14 @@ int ogs_nas_5gs_encode_eps_bearer_context_status(ogs_pkbuf_t *pkbuf, ogs_nas_eps
int ogs_nas_5gs_decode_eps_nas_message_container(ogs_nas_eps_nas_message_container_t *eps_nas_message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_nas_message_container_t *source = (ogs_nas_eps_nas_message_container_t *)pkbuf->data;
+ ogs_nas_eps_nas_message_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_nas_message_container_t *)pkbuf->data;
eps_nas_message_container->length = be16toh(source->length);
size = eps_nas_message_container->length + sizeof(eps_nas_message_container->length);
@@ -1155,7 +1302,14 @@ int ogs_nas_5gs_encode_eps_nas_security_algorithms(ogs_pkbuf_t *pkbuf, ogs_nas_e
int ogs_nas_5gs_decode_extended_emergency_number_list(ogs_nas_extended_emergency_number_list_t *extended_emergency_number_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_emergency_number_list_t *source = (ogs_nas_extended_emergency_number_list_t *)pkbuf->data;
+ ogs_nas_extended_emergency_number_list_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_emergency_number_list_t *)pkbuf->data;
extended_emergency_number_list->length = be16toh(source->length);
size = extended_emergency_number_list->length + sizeof(extended_emergency_number_list->length);
@@ -1201,7 +1355,14 @@ int ogs_nas_5gs_encode_extended_emergency_number_list(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_5gs_decode_extended_drx_parameters(ogs_nas_extended_drx_parameters_t *extended_drx_parameters, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_drx_parameters_t *source = (ogs_nas_extended_drx_parameters_t *)pkbuf->data;
+ ogs_nas_extended_drx_parameters_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_drx_parameters_t *)pkbuf->data;
extended_drx_parameters->length = source->length;
size = extended_drx_parameters->length + sizeof(extended_drx_parameters->length);
@@ -1272,7 +1433,14 @@ int ogs_nas_5gs_encode_imeisv_request(ogs_pkbuf_t *pkbuf, ogs_nas_imeisv_request
int ogs_nas_5gs_decode_ladn_indication(ogs_nas_ladn_indication_t *ladn_indication, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ladn_indication_t *source = (ogs_nas_ladn_indication_t *)pkbuf->data;
+ ogs_nas_ladn_indication_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ladn_indication_t *)pkbuf->data;
ladn_indication->length = be16toh(source->length);
size = ladn_indication->length + sizeof(ladn_indication->length);
@@ -1318,7 +1486,14 @@ int ogs_nas_5gs_encode_ladn_indication(ogs_pkbuf_t *pkbuf, ogs_nas_ladn_indicati
int ogs_nas_5gs_decode_5gs_drx_parameters(ogs_nas_5gs_drx_parameters_t *drx_parameters, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_drx_parameters_t *source = (ogs_nas_5gs_drx_parameters_t *)pkbuf->data;
+ ogs_nas_5gs_drx_parameters_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_drx_parameters_t *)pkbuf->data;
drx_parameters->length = source->length;
size = drx_parameters->length + sizeof(drx_parameters->length);
@@ -1391,7 +1566,14 @@ int ogs_nas_5gs_encode_5gs_identity_type(ogs_pkbuf_t *pkbuf, ogs_nas_5gs_identit
int ogs_nas_5gs_decode_ladn_information(ogs_nas_ladn_information_t *ladn_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ladn_information_t *source = (ogs_nas_ladn_information_t *)pkbuf->data;
+ ogs_nas_ladn_information_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ladn_information_t *)pkbuf->data;
ladn_information->length = be16toh(source->length);
size = ladn_information->length + sizeof(ladn_information->length);
@@ -1501,7 +1683,14 @@ int ogs_nas_5gs_encode_ma_pdu_session_information(ogs_pkbuf_t *pkbuf, ogs_nas_ma
int ogs_nas_5gs_decode_mapped_nssai(ogs_nas_mapped_nssai_t *mapped_nssai, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mapped_nssai_t *source = (ogs_nas_mapped_nssai_t *)pkbuf->data;
+ ogs_nas_mapped_nssai_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mapped_nssai_t *)pkbuf->data;
mapped_nssai->length = source->length;
size = mapped_nssai->length + sizeof(mapped_nssai->length);
@@ -1540,7 +1729,14 @@ int ogs_nas_5gs_encode_mapped_nssai(ogs_pkbuf_t *pkbuf, ogs_nas_mapped_nssai_t *
int ogs_nas_5gs_decode_mobile_station_classmark_2(ogs_nas_mobile_station_classmark_2_t *mobile_station_classmark_2, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mobile_station_classmark_2_t *source = (ogs_nas_mobile_station_classmark_2_t *)pkbuf->data;
+ ogs_nas_mobile_station_classmark_2_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mobile_station_classmark_2_t *)pkbuf->data;
mobile_station_classmark_2->length = source->length;
size = mobile_station_classmark_2->length + sizeof(mobile_station_classmark_2->length);
@@ -1611,7 +1807,14 @@ int ogs_nas_5gs_encode_key_set_identifier(ogs_pkbuf_t *pkbuf, ogs_nas_key_set_id
int ogs_nas_5gs_decode_message_container(ogs_nas_message_container_t *message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_message_container_t *source = (ogs_nas_message_container_t *)pkbuf->data;
+ ogs_nas_message_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_message_container_t *)pkbuf->data;
message_container->length = be16toh(source->length);
size = message_container->length + sizeof(message_container->length);
@@ -1691,7 +1894,14 @@ int ogs_nas_5gs_encode_security_algorithms(ogs_pkbuf_t *pkbuf, ogs_nas_security_
int ogs_nas_5gs_decode_network_name(ogs_nas_network_name_t *network_name, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_network_name_t *source = (ogs_nas_network_name_t *)pkbuf->data;
+ ogs_nas_network_name_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_network_name_t *)pkbuf->data;
network_name->length = source->length;
size = network_name->length + sizeof(network_name->length);
@@ -1794,7 +2004,14 @@ int ogs_nas_5gs_encode_non_3gpp_nw_provided_policies(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_5gs_decode_nssai(ogs_nas_nssai_t *nssai, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nssai_t *source = (ogs_nas_nssai_t *)pkbuf->data;
+ ogs_nas_nssai_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nssai_t *)pkbuf->data;
nssai->length = source->length;
size = nssai->length + sizeof(nssai->length);
@@ -1865,7 +2082,14 @@ int ogs_nas_5gs_encode_nssai_inclusion_mode(ogs_pkbuf_t *pkbuf, ogs_nas_nssai_in
int ogs_nas_5gs_decode_operator_defined_access_category_definitions(ogs_nas_operator_defined_access_category_definitions_t *operator_defined_access_category_definitions, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_operator_defined_access_category_definitions_t *source = (ogs_nas_operator_defined_access_category_definitions_t *)pkbuf->data;
+ ogs_nas_operator_defined_access_category_definitions_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_operator_defined_access_category_definitions_t *)pkbuf->data;
operator_defined_access_category_definitions->length = be16toh(source->length);
size = operator_defined_access_category_definitions->length + sizeof(operator_defined_access_category_definitions->length);
@@ -1911,7 +2135,14 @@ int ogs_nas_5gs_encode_operator_defined_access_category_definitions(ogs_pkbuf_t
int ogs_nas_5gs_decode_payload_container(ogs_nas_payload_container_t *payload_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_payload_container_t *source = (ogs_nas_payload_container_t *)pkbuf->data;
+ ogs_nas_payload_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_payload_container_t *)pkbuf->data;
payload_container->length = be16toh(source->length);
size = payload_container->length + sizeof(payload_container->length);
@@ -1957,7 +2188,14 @@ int ogs_nas_5gs_encode_payload_container(ogs_pkbuf_t *pkbuf, ogs_nas_payload_con
int ogs_nas_5gs_decode_5gs_mobile_identity(ogs_nas_5gs_mobile_identity_t *mobile_identity, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_mobile_identity_t *source = (ogs_nas_5gs_mobile_identity_t *)pkbuf->data;
+ ogs_nas_5gs_mobile_identity_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_mobile_identity_t *)pkbuf->data;
mobile_identity->length = be16toh(source->length);
size = mobile_identity->length + sizeof(mobile_identity->length);
@@ -2069,7 +2307,14 @@ int ogs_nas_5gs_encode_pdu_session_identity_2(ogs_pkbuf_t *pkbuf, ogs_nas_pdu_se
int ogs_nas_5gs_decode_pdu_session_reactivation_result(ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdu_session_reactivation_result_t *source = (ogs_nas_pdu_session_reactivation_result_t *)pkbuf->data;
+ ogs_nas_pdu_session_reactivation_result_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdu_session_reactivation_result_t *)pkbuf->data;
pdu_session_reactivation_result->length = source->length;
size = pdu_session_reactivation_result->length + sizeof(pdu_session_reactivation_result->length);
@@ -2112,7 +2357,14 @@ int ogs_nas_5gs_encode_pdu_session_reactivation_result(ogs_pkbuf_t *pkbuf, ogs_n
int ogs_nas_5gs_decode_pdu_session_reactivation_result_error_cause(ogs_nas_pdu_session_reactivation_result_error_cause_t *pdu_session_reactivation_result_error_cause, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdu_session_reactivation_result_error_cause_t *source = (ogs_nas_pdu_session_reactivation_result_error_cause_t *)pkbuf->data;
+ ogs_nas_pdu_session_reactivation_result_error_cause_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdu_session_reactivation_result_error_cause_t *)pkbuf->data;
pdu_session_reactivation_result_error_cause->length = be16toh(source->length);
size = pdu_session_reactivation_result_error_cause->length + sizeof(pdu_session_reactivation_result_error_cause->length);
@@ -2158,7 +2410,14 @@ int ogs_nas_5gs_encode_pdu_session_reactivation_result_error_cause(ogs_pkbuf_t *
int ogs_nas_5gs_decode_pdu_session_status(ogs_nas_pdu_session_status_t *pdu_session_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdu_session_status_t *source = (ogs_nas_pdu_session_status_t *)pkbuf->data;
+ ogs_nas_pdu_session_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdu_session_status_t *)pkbuf->data;
pdu_session_status->length = source->length;
size = pdu_session_status->length + sizeof(pdu_session_status->length);
@@ -2201,7 +2460,14 @@ int ogs_nas_5gs_encode_pdu_session_status(ogs_pkbuf_t *pkbuf, ogs_nas_pdu_sessio
int ogs_nas_5gs_decode_plmn_list(ogs_nas_plmn_list_t *plmn_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_plmn_list_t *source = (ogs_nas_plmn_list_t *)pkbuf->data;
+ ogs_nas_plmn_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_plmn_list_t *)pkbuf->data;
plmn_list->length = source->length;
size = plmn_list->length + sizeof(plmn_list->length);
@@ -2240,7 +2506,14 @@ int ogs_nas_5gs_encode_plmn_list(ogs_pkbuf_t *pkbuf, ogs_nas_plmn_list_t *plmn_l
int ogs_nas_5gs_decode_rejected_nssai(ogs_nas_rejected_nssai_t *rejected_nssai, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_rejected_nssai_t *source = (ogs_nas_rejected_nssai_t *)pkbuf->data;
+ ogs_nas_rejected_nssai_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_rejected_nssai_t *)pkbuf->data;
rejected_nssai->length = source->length;
size = rejected_nssai->length + sizeof(rejected_nssai->length);
@@ -2343,7 +2616,14 @@ int ogs_nas_5gs_encode_request_type(ogs_pkbuf_t *pkbuf, ogs_nas_request_type_t *
int ogs_nas_5gs_decode_s1_ue_network_capability(ogs_nas_s1_ue_network_capability_t *s1_ue_network_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_s1_ue_network_capability_t *source = (ogs_nas_s1_ue_network_capability_t *)pkbuf->data;
+ ogs_nas_s1_ue_network_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_s1_ue_network_capability_t *)pkbuf->data;
s1_ue_network_capability->length = source->length;
size = s1_ue_network_capability->length + sizeof(s1_ue_network_capability->length);
@@ -2382,7 +2662,14 @@ int ogs_nas_5gs_encode_s1_ue_network_capability(ogs_pkbuf_t *pkbuf, ogs_nas_s1_u
int ogs_nas_5gs_decode_s1_ue_security_capability(ogs_nas_s1_ue_security_capability_t *s1_ue_security_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_s1_ue_security_capability_t *source = (ogs_nas_s1_ue_security_capability_t *)pkbuf->data;
+ ogs_nas_s1_ue_security_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_s1_ue_security_capability_t *)pkbuf->data;
s1_ue_security_capability->length = source->length;
size = s1_ue_security_capability->length + sizeof(s1_ue_security_capability->length);
@@ -2421,7 +2708,14 @@ int ogs_nas_5gs_encode_s1_ue_security_capability(ogs_pkbuf_t *pkbuf, ogs_nas_s1_
int ogs_nas_5gs_decode_service_area_list(ogs_nas_service_area_list_t *service_area_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_service_area_list_t *source = (ogs_nas_service_area_list_t *)pkbuf->data;
+ ogs_nas_service_area_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_service_area_list_t *)pkbuf->data;
service_area_list->length = source->length;
size = service_area_list->length + sizeof(service_area_list->length);
@@ -2460,7 +2754,14 @@ int ogs_nas_5gs_encode_service_area_list(ogs_pkbuf_t *pkbuf, ogs_nas_service_are
int ogs_nas_5gs_decode_5gs_network_feature_support(ogs_nas_5gs_network_feature_support_t *network_feature_support, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_network_feature_support_t *source = (ogs_nas_5gs_network_feature_support_t *)pkbuf->data;
+ ogs_nas_5gs_network_feature_support_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_network_feature_support_t *)pkbuf->data;
network_feature_support->length = source->length;
size = network_feature_support->length + sizeof(network_feature_support->length);
@@ -2531,7 +2832,14 @@ int ogs_nas_5gs_encode_sms_indication(ogs_pkbuf_t *pkbuf, ogs_nas_sms_indication
int ogs_nas_5gs_decode_sor_transparent_container(ogs_nas_sor_transparent_container_t *sor_transparent_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_sor_transparent_container_t *source = (ogs_nas_sor_transparent_container_t *)pkbuf->data;
+ ogs_nas_sor_transparent_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_sor_transparent_container_t *)pkbuf->data;
sor_transparent_container->length = be16toh(source->length);
size = sor_transparent_container->length + sizeof(sor_transparent_container->length);
@@ -2577,7 +2885,14 @@ int ogs_nas_5gs_encode_sor_transparent_container(ogs_pkbuf_t *pkbuf, ogs_nas_sor
int ogs_nas_5gs_decode_supported_codec_list(ogs_nas_supported_codec_list_t *supported_codec_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_supported_codec_list_t *source = (ogs_nas_supported_codec_list_t *)pkbuf->data;
+ ogs_nas_supported_codec_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_supported_codec_list_t *)pkbuf->data;
supported_codec_list->length = source->length;
size = supported_codec_list->length + sizeof(supported_codec_list->length);
@@ -2684,7 +2999,14 @@ int ogs_nas_5gs_encode_time_zone_and_time(ogs_pkbuf_t *pkbuf, ogs_nas_time_zone_
int ogs_nas_5gs_decode_ue_security_capability(ogs_nas_ue_security_capability_t *ue_security_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_security_capability_t *source = (ogs_nas_ue_security_capability_t *)pkbuf->data;
+ ogs_nas_ue_security_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_security_capability_t *)pkbuf->data;
ue_security_capability->length = source->length;
size = ue_security_capability->length + sizeof(ue_security_capability->length);
@@ -2723,7 +3045,14 @@ int ogs_nas_5gs_encode_ue_security_capability(ogs_pkbuf_t *pkbuf, ogs_nas_ue_sec
int ogs_nas_5gs_decode_ue_usage_setting(ogs_nas_ue_usage_setting_t *ue_usage_setting, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_usage_setting_t *source = (ogs_nas_ue_usage_setting_t *)pkbuf->data;
+ ogs_nas_ue_usage_setting_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_usage_setting_t *)pkbuf->data;
ue_usage_setting->length = source->length;
size = ue_usage_setting->length + sizeof(ue_usage_setting->length);
@@ -2762,7 +3091,14 @@ int ogs_nas_5gs_encode_ue_usage_setting(ogs_pkbuf_t *pkbuf, ogs_nas_ue_usage_set
int ogs_nas_5gs_decode_ue_status(ogs_nas_ue_status_t *ue_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_status_t *source = (ogs_nas_ue_status_t *)pkbuf->data;
+ ogs_nas_ue_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_status_t *)pkbuf->data;
ue_status->length = source->length;
size = ue_status->length + sizeof(ue_status->length);
@@ -2801,7 +3137,14 @@ int ogs_nas_5gs_encode_ue_status(ogs_pkbuf_t *pkbuf, ogs_nas_ue_status_t *ue_sta
int ogs_nas_5gs_decode_uplink_data_status(ogs_nas_uplink_data_status_t *uplink_data_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_uplink_data_status_t *source = (ogs_nas_uplink_data_status_t *)pkbuf->data;
+ ogs_nas_uplink_data_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_uplink_data_status_t *)pkbuf->data;
uplink_data_status->length = source->length;
size = uplink_data_status->length + sizeof(uplink_data_status->length);
@@ -2844,7 +3187,14 @@ int ogs_nas_5gs_encode_uplink_data_status(ogs_pkbuf_t *pkbuf, ogs_nas_uplink_dat
int ogs_nas_5gs_decode_5gs_registration_result(ogs_nas_5gs_registration_result_t *registration_result, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_registration_result_t *source = (ogs_nas_5gs_registration_result_t *)pkbuf->data;
+ ogs_nas_5gs_registration_result_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_registration_result_t *)pkbuf->data;
registration_result->length = source->length;
size = registration_result->length + sizeof(registration_result->length);
@@ -2883,7 +3233,14 @@ int ogs_nas_5gs_encode_5gs_registration_result(ogs_pkbuf_t *pkbuf, ogs_nas_5gs_r
int ogs_nas_5gs_decode_ue_radio_capability_id(ogs_nas_ue_radio_capability_id_t *ue_radio_capability_id, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_radio_capability_id_t *source = (ogs_nas_ue_radio_capability_id_t *)pkbuf->data;
+ ogs_nas_ue_radio_capability_id_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_radio_capability_id_t *)pkbuf->data;
ue_radio_capability_id->length = source->length;
size = ue_radio_capability_id->length + sizeof(ue_radio_capability_id->length);
@@ -2988,7 +3345,14 @@ int ogs_nas_5gs_encode_5gs_registration_type(ogs_pkbuf_t *pkbuf, ogs_nas_5gs_reg
int ogs_nas_5gs_decode_truncated_5g_s_tmsi_configuration(ogs_nas_truncated_5g_s_tmsi_configuration_t *truncated_s_tmsi_configuration, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_truncated_5g_s_tmsi_configuration_t *source = (ogs_nas_truncated_5g_s_tmsi_configuration_t *)pkbuf->data;
+ ogs_nas_truncated_5g_s_tmsi_configuration_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_truncated_5g_s_tmsi_configuration_t *)pkbuf->data;
truncated_s_tmsi_configuration->length = source->length;
size = truncated_s_tmsi_configuration->length + sizeof(truncated_s_tmsi_configuration->length);
@@ -3027,7 +3391,14 @@ int ogs_nas_5gs_encode_truncated_5g_s_tmsi_configuration(ogs_pkbuf_t *pkbuf, ogs
int ogs_nas_5gs_decode_wus_assistance_information(ogs_nas_wus_assistance_information_t *wus_assistance_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_wus_assistance_information_t *source = (ogs_nas_wus_assistance_information_t *)pkbuf->data;
+ ogs_nas_wus_assistance_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_wus_assistance_information_t *)pkbuf->data;
wus_assistance_information->length = source->length;
size = wus_assistance_information->length + sizeof(wus_assistance_information->length);
@@ -3098,7 +3469,14 @@ int ogs_nas_5gs_encode_n5gc_indication(ogs_pkbuf_t *pkbuf, ogs_nas_n5gc_indicati
int ogs_nas_5gs_decode_nb_n1_mode_drx_parameters(ogs_nas_nb_n1_mode_drx_parameters_t *nb_n1_mode_drx_parameters, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nb_n1_mode_drx_parameters_t *source = (ogs_nas_nb_n1_mode_drx_parameters_t *)pkbuf->data;
+ ogs_nas_nb_n1_mode_drx_parameters_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nb_n1_mode_drx_parameters_t *)pkbuf->data;
nb_n1_mode_drx_parameters->length = source->length;
size = nb_n1_mode_drx_parameters->length + sizeof(nb_n1_mode_drx_parameters->length);
@@ -3169,7 +3547,14 @@ int ogs_nas_5gs_encode_additional_configuration_indication(ogs_pkbuf_t *pkbuf, o
int ogs_nas_5gs_decode_extended_rejected_nssai(ogs_nas_extended_rejected_nssai_t *extended_rejected_nssai, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_rejected_nssai_t *source = (ogs_nas_extended_rejected_nssai_t *)pkbuf->data;
+ ogs_nas_extended_rejected_nssai_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_rejected_nssai_t *)pkbuf->data;
extended_rejected_nssai->length = source->length;
size = extended_rejected_nssai->length + sizeof(extended_rejected_nssai->length);
@@ -3208,7 +3593,14 @@ int ogs_nas_5gs_encode_extended_rejected_nssai(ogs_pkbuf_t *pkbuf, ogs_nas_exten
int ogs_nas_5gs_decode_ue_request_type(ogs_nas_ue_request_type_t *ue_request_type, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_request_type_t *source = (ogs_nas_ue_request_type_t *)pkbuf->data;
+ ogs_nas_ue_request_type_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_request_type_t *)pkbuf->data;
ue_request_type->length = source->length;
size = ue_request_type->length + sizeof(ue_request_type->length);
@@ -3247,7 +3639,14 @@ int ogs_nas_5gs_encode_ue_request_type(ogs_pkbuf_t *pkbuf, ogs_nas_ue_request_ty
int ogs_nas_5gs_decode_paging_restriction(ogs_nas_paging_restriction_t *paging_restriction, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_paging_restriction_t *source = (ogs_nas_paging_restriction_t *)pkbuf->data;
+ ogs_nas_paging_restriction_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_paging_restriction_t *)pkbuf->data;
paging_restriction->length = source->length;
size = paging_restriction->length + sizeof(paging_restriction->length);
@@ -3286,7 +3685,14 @@ int ogs_nas_5gs_encode_paging_restriction(ogs_pkbuf_t *pkbuf, ogs_nas_paging_res
int ogs_nas_5gs_decode_nid(ogs_nas_nid_t *nid, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nid_t *source = (ogs_nas_nid_t *)pkbuf->data;
+ ogs_nas_nid_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nid_t *)pkbuf->data;
nid->length = source->length;
size = nid->length + sizeof(nid->length);
@@ -3363,7 +3769,14 @@ int ogs_nas_5gs_encode_5gs_tracking_area_identity(ogs_pkbuf_t *pkbuf, ogs_nas_5g
int ogs_nas_5gs_decode_peips_assistance_information(ogs_nas_peips_assistance_information_t *peips_assistance_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_peips_assistance_information_t *source = (ogs_nas_peips_assistance_information_t *)pkbuf->data;
+ ogs_nas_peips_assistance_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_peips_assistance_information_t *)pkbuf->data;
peips_assistance_information->length = source->length;
size = peips_assistance_information->length + sizeof(peips_assistance_information->length);
@@ -3402,7 +3815,14 @@ int ogs_nas_5gs_encode_peips_assistance_information(ogs_pkbuf_t *pkbuf, ogs_nas_
int ogs_nas_5gs_decode_5gs_additional_request_result(ogs_nas_5gs_additional_request_result_t *additional_request_result, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_additional_request_result_t *source = (ogs_nas_5gs_additional_request_result_t *)pkbuf->data;
+ ogs_nas_5gs_additional_request_result_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_additional_request_result_t *)pkbuf->data;
additional_request_result->length = source->length;
size = additional_request_result->length + sizeof(additional_request_result->length);
@@ -3441,7 +3861,14 @@ int ogs_nas_5gs_encode_5gs_additional_request_result(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_5gs_decode_nssrg_information(ogs_nas_nssrg_information_t *nssrg_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nssrg_information_t *source = (ogs_nas_nssrg_information_t *)pkbuf->data;
+ ogs_nas_nssrg_information_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nssrg_information_t *)pkbuf->data;
nssrg_information->length = be16toh(source->length);
size = nssrg_information->length + sizeof(nssrg_information->length);
@@ -3487,7 +3914,14 @@ int ogs_nas_5gs_encode_nssrg_information(ogs_pkbuf_t *pkbuf, ogs_nas_nssrg_infor
int ogs_nas_5gs_decode_list_of_plmns_to_be_used_in_disaster_condition(ogs_nas_list_of_plmns_to_be_used_in_disaster_condition_t *list_of_plmns_to_be_used_in_disaster_condition, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_list_of_plmns_to_be_used_in_disaster_condition_t *source = (ogs_nas_list_of_plmns_to_be_used_in_disaster_condition_t *)pkbuf->data;
+ ogs_nas_list_of_plmns_to_be_used_in_disaster_condition_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_list_of_plmns_to_be_used_in_disaster_condition_t *)pkbuf->data;
list_of_plmns_to_be_used_in_disaster_condition->length = source->length;
size = list_of_plmns_to_be_used_in_disaster_condition->length + sizeof(list_of_plmns_to_be_used_in_disaster_condition->length);
@@ -3526,7 +3960,14 @@ int ogs_nas_5gs_encode_list_of_plmns_to_be_used_in_disaster_condition(ogs_pkbuf_
int ogs_nas_5gs_decode_registration_wait_range(ogs_nas_registration_wait_range_t *registration_wait_range, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_registration_wait_range_t *source = (ogs_nas_registration_wait_range_t *)pkbuf->data;
+ ogs_nas_registration_wait_range_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_registration_wait_range_t *)pkbuf->data;
registration_wait_range->length = source->length;
size = registration_wait_range->length + sizeof(registration_wait_range->length);
@@ -3565,7 +4006,14 @@ int ogs_nas_5gs_encode_registration_wait_range(ogs_pkbuf_t *pkbuf, ogs_nas_regis
int ogs_nas_5gs_decode_plmn_identity(ogs_nas_plmn_identity_t *plmn_identity, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_plmn_identity_t *source = (ogs_nas_plmn_identity_t *)pkbuf->data;
+ ogs_nas_plmn_identity_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_plmn_identity_t *)pkbuf->data;
plmn_identity->length = source->length;
size = plmn_identity->length + sizeof(plmn_identity->length);
@@ -3604,7 +4052,14 @@ int ogs_nas_5gs_encode_plmn_identity(ogs_pkbuf_t *pkbuf, ogs_nas_plmn_identity_t
int ogs_nas_5gs_decode_extended_cag_information_list(ogs_nas_extended_cag_information_list_t *extended_cag_information_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_cag_information_list_t *source = (ogs_nas_extended_cag_information_list_t *)pkbuf->data;
+ ogs_nas_extended_cag_information_list_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_cag_information_list_t *)pkbuf->data;
extended_cag_information_list->length = be16toh(source->length);
size = extended_cag_information_list->length + sizeof(extended_cag_information_list->length);
@@ -3650,7 +4105,14 @@ int ogs_nas_5gs_encode_extended_cag_information_list(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_5gs_decode_nsag_information(ogs_nas_nsag_information_t *nsag_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nsag_information_t *source = (ogs_nas_nsag_information_t *)pkbuf->data;
+ ogs_nas_nsag_information_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nsag_information_t *)pkbuf->data;
nsag_information->length = be16toh(source->length);
size = nsag_information->length + sizeof(nsag_information->length);
@@ -3696,7 +4158,14 @@ int ogs_nas_5gs_encode_nsag_information(ogs_pkbuf_t *pkbuf, ogs_nas_nsag_informa
int ogs_nas_5gs_decode_5gs_tracking_area_identity_list(ogs_nas_5gs_tracking_area_identity_list_t *tracking_area_identity_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_tracking_area_identity_list_t *source = (ogs_nas_5gs_tracking_area_identity_list_t *)pkbuf->data;
+ ogs_nas_5gs_tracking_area_identity_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_tracking_area_identity_list_t *)pkbuf->data;
tracking_area_identity_list->length = source->length;
size = tracking_area_identity_list->length + sizeof(tracking_area_identity_list->length);
@@ -3767,7 +4236,14 @@ int ogs_nas_5gs_encode_priority_indicator(ogs_pkbuf_t *pkbuf, ogs_nas_priority_i
int ogs_nas_5gs_decode_5gs_update_type(ogs_nas_5gs_update_type_t *update_type, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gs_update_type_t *source = (ogs_nas_5gs_update_type_t *)pkbuf->data;
+ ogs_nas_5gs_update_type_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gs_update_type_t *)pkbuf->data;
update_type->length = source->length;
size = update_type->length + sizeof(update_type->length);
@@ -3806,7 +4282,14 @@ int ogs_nas_5gs_encode_5gs_update_type(ogs_pkbuf_t *pkbuf, ogs_nas_5gs_update_ty
int ogs_nas_5gs_decode_5gsm_capability(ogs_nas_5gsm_capability_t *gsm_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gsm_capability_t *source = (ogs_nas_5gsm_capability_t *)pkbuf->data;
+ ogs_nas_5gsm_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gsm_capability_t *)pkbuf->data;
gsm_capability->length = source->length;
size = gsm_capability->length + sizeof(gsm_capability->length);
@@ -3845,7 +4328,14 @@ int ogs_nas_5gs_encode_5gsm_capability(ogs_pkbuf_t *pkbuf, ogs_nas_5gsm_capabili
int ogs_nas_5gs_decode_pdu_address(ogs_nas_pdu_address_t *pdu_address, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdu_address_t *source = (ogs_nas_pdu_address_t *)pkbuf->data;
+ ogs_nas_pdu_address_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdu_address_t *)pkbuf->data;
pdu_address->length = source->length;
size = pdu_address->length + sizeof(pdu_address->length);
@@ -3916,7 +4406,14 @@ int ogs_nas_5gs_encode_pdu_session_type(ogs_pkbuf_t *pkbuf, ogs_nas_pdu_session_
int ogs_nas_5gs_decode_qos_flow_descriptions(ogs_nas_qos_flow_descriptions_t *qos_flow_descriptions, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_qos_flow_descriptions_t *source = (ogs_nas_qos_flow_descriptions_t *)pkbuf->data;
+ ogs_nas_qos_flow_descriptions_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_qos_flow_descriptions_t *)pkbuf->data;
qos_flow_descriptions->length = be16toh(source->length);
size = qos_flow_descriptions->length + sizeof(qos_flow_descriptions->length);
@@ -3962,7 +4459,14 @@ int ogs_nas_5gs_encode_qos_flow_descriptions(ogs_pkbuf_t *pkbuf, ogs_nas_qos_flo
int ogs_nas_5gs_decode_qos_rules(ogs_nas_qos_rules_t *qos_rules, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_qos_rules_t *source = (ogs_nas_qos_rules_t *)pkbuf->data;
+ ogs_nas_qos_rules_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_qos_rules_t *)pkbuf->data;
qos_rules->length = be16toh(source->length);
size = qos_rules->length + sizeof(qos_rules->length);
@@ -4008,7 +4512,14 @@ int ogs_nas_5gs_encode_qos_rules(ogs_pkbuf_t *pkbuf, ogs_nas_qos_rules_t *qos_ru
int ogs_nas_5gs_decode_session_ambr(ogs_nas_session_ambr_t *session_ambr, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_session_ambr_t *source = (ogs_nas_session_ambr_t *)pkbuf->data;
+ ogs_nas_session_ambr_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_session_ambr_t *)pkbuf->data;
session_ambr->length = source->length;
size = session_ambr->length + sizeof(session_ambr->length);
@@ -4053,7 +4564,14 @@ int ogs_nas_5gs_encode_session_ambr(ogs_pkbuf_t *pkbuf, ogs_nas_session_ambr_t *
int ogs_nas_5gs_decode_sm_pdu_dn_request_container(ogs_nas_sm_pdu_dn_request_container_t *sm_pdu_dn_request_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_sm_pdu_dn_request_container_t *source = (ogs_nas_sm_pdu_dn_request_container_t *)pkbuf->data;
+ ogs_nas_sm_pdu_dn_request_container_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_sm_pdu_dn_request_container_t *)pkbuf->data;
sm_pdu_dn_request_container->length = source->length;
size = sm_pdu_dn_request_container->length + sizeof(sm_pdu_dn_request_container->length);
@@ -4124,7 +4642,14 @@ int ogs_nas_5gs_encode_ssc_mode(ogs_pkbuf_t *pkbuf, ogs_nas_ssc_mode_t *ssc_mode
int ogs_nas_5gs_decode_re_attempt_indicator(ogs_nas_re_attempt_indicator_t *re_attempt_indicator, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_re_attempt_indicator_t *source = (ogs_nas_re_attempt_indicator_t *)pkbuf->data;
+ ogs_nas_re_attempt_indicator_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_re_attempt_indicator_t *)pkbuf->data;
re_attempt_indicator->length = source->length;
size = re_attempt_indicator->length + sizeof(re_attempt_indicator->length);
@@ -4163,7 +4688,14 @@ int ogs_nas_5gs_encode_re_attempt_indicator(ogs_pkbuf_t *pkbuf, ogs_nas_re_attem
int ogs_nas_5gs_decode_5gsm_network_feature_support(ogs_nas_5gsm_network_feature_support_t *gsm_network_feature_support, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gsm_network_feature_support_t *source = (ogs_nas_5gsm_network_feature_support_t *)pkbuf->data;
+ ogs_nas_5gsm_network_feature_support_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gsm_network_feature_support_t *)pkbuf->data;
gsm_network_feature_support->length = source->length;
size = gsm_network_feature_support->length + sizeof(gsm_network_feature_support->length);
@@ -4236,7 +4768,14 @@ int ogs_nas_5gs_encode_5gsm_cause(ogs_pkbuf_t *pkbuf, ogs_nas_5gsm_cause_t *gsm_
int ogs_nas_5gs_decode_serving_plmn_rate_control(ogs_nas_serving_plmn_rate_control_t *serving_plmn_rate_control, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_serving_plmn_rate_control_t *source = (ogs_nas_serving_plmn_rate_control_t *)pkbuf->data;
+ ogs_nas_serving_plmn_rate_control_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_serving_plmn_rate_control_t *)pkbuf->data;
serving_plmn_rate_control->length = source->length;
size = serving_plmn_rate_control->length + sizeof(serving_plmn_rate_control->length);
@@ -4275,7 +4814,14 @@ int ogs_nas_5gs_encode_serving_plmn_rate_control(ogs_pkbuf_t *pkbuf, ogs_nas_ser
int ogs_nas_5gs_decode_5gsm_congestion_re_attempt_indicator(ogs_nas_5gsm_congestion_re_attempt_indicator_t *gsm_congestion_re_attempt_indicator, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_5gsm_congestion_re_attempt_indicator_t *source = (ogs_nas_5gsm_congestion_re_attempt_indicator_t *)pkbuf->data;
+ ogs_nas_5gsm_congestion_re_attempt_indicator_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_5gsm_congestion_re_attempt_indicator_t *)pkbuf->data;
gsm_congestion_re_attempt_indicator->length = source->length;
size = gsm_congestion_re_attempt_indicator->length + sizeof(gsm_congestion_re_attempt_indicator->length);
@@ -4314,7 +4860,14 @@ int ogs_nas_5gs_encode_5gsm_congestion_re_attempt_indicator(ogs_pkbuf_t *pkbuf,
int ogs_nas_5gs_decode_atsss_container(ogs_nas_atsss_container_t *atsss_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_atsss_container_t *source = (ogs_nas_atsss_container_t *)pkbuf->data;
+ ogs_nas_atsss_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_atsss_container_t *)pkbuf->data;
atsss_container->length = be16toh(source->length);
size = atsss_container->length + sizeof(atsss_container->length);
@@ -4392,7 +4945,14 @@ int ogs_nas_5gs_encode_control_plane_only_indication(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_5gs_decode_ip_header_compression_configuration(ogs_nas_ip_header_compression_configuration_t *ip_header_compression_configuration, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ip_header_compression_configuration_t *source = (ogs_nas_ip_header_compression_configuration_t *)pkbuf->data;
+ ogs_nas_ip_header_compression_configuration_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ip_header_compression_configuration_t *)pkbuf->data;
ip_header_compression_configuration->length = source->length;
size = ip_header_compression_configuration->length + sizeof(ip_header_compression_configuration->length);
@@ -4431,7 +4991,14 @@ int ogs_nas_5gs_encode_ip_header_compression_configuration(ogs_pkbuf_t *pkbuf, o
int ogs_nas_5gs_decode_header_compression_configuration(ogs_nas_header_compression_configuration_t *header_compression_configuration, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_header_compression_configuration_t *source = (ogs_nas_header_compression_configuration_t *)pkbuf->data;
+ ogs_nas_header_compression_configuration_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_header_compression_configuration_t *)pkbuf->data;
header_compression_configuration->length = source->length;
size = header_compression_configuration->length + sizeof(header_compression_configuration->length);
@@ -4474,7 +5041,14 @@ int ogs_nas_5gs_encode_header_compression_configuration(ogs_pkbuf_t *pkbuf, ogs_
int ogs_nas_5gs_decode_ds_tt_ethernet_port_mac_address(ogs_nas_ds_tt_ethernet_port_mac_address_t *ds_tt_ethernet_port_mac_address, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ds_tt_ethernet_port_mac_address_t *source = (ogs_nas_ds_tt_ethernet_port_mac_address_t *)pkbuf->data;
+ ogs_nas_ds_tt_ethernet_port_mac_address_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ds_tt_ethernet_port_mac_address_t *)pkbuf->data;
ds_tt_ethernet_port_mac_address->length = source->length;
size = ds_tt_ethernet_port_mac_address->length + sizeof(ds_tt_ethernet_port_mac_address->length);
@@ -4513,7 +5087,14 @@ int ogs_nas_5gs_encode_ds_tt_ethernet_port_mac_address(ogs_pkbuf_t *pkbuf, ogs_n
int ogs_nas_5gs_decode_ue_ds_tt_residence_time(ogs_nas_ue_ds_tt_residence_time_t *ue_ds_tt_residence_time, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_ds_tt_residence_time_t *source = (ogs_nas_ue_ds_tt_residence_time_t *)pkbuf->data;
+ ogs_nas_ue_ds_tt_residence_time_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_ds_tt_residence_time_t *)pkbuf->data;
ue_ds_tt_residence_time->length = source->length;
size = ue_ds_tt_residence_time->length + sizeof(ue_ds_tt_residence_time->length);
@@ -4552,7 +5133,14 @@ int ogs_nas_5gs_encode_ue_ds_tt_residence_time(ogs_pkbuf_t *pkbuf, ogs_nas_ue_ds
int ogs_nas_5gs_decode_port_management_information_container(ogs_nas_port_management_information_container_t *port_management_information_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_port_management_information_container_t *source = (ogs_nas_port_management_information_container_t *)pkbuf->data;
+ ogs_nas_port_management_information_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_port_management_information_container_t *)pkbuf->data;
port_management_information_container->length = be16toh(source->length);
size = port_management_information_container->length + sizeof(port_management_information_container->length);
@@ -4598,7 +5186,14 @@ int ogs_nas_5gs_encode_port_management_information_container(ogs_pkbuf_t *pkbuf,
int ogs_nas_5gs_decode_ethernet_header_compression_configuration(ogs_nas_ethernet_header_compression_configuration_t *ethernet_header_compression_configuration, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ethernet_header_compression_configuration_t *source = (ogs_nas_ethernet_header_compression_configuration_t *)pkbuf->data;
+ ogs_nas_ethernet_header_compression_configuration_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ethernet_header_compression_configuration_t *)pkbuf->data;
ethernet_header_compression_configuration->length = source->length;
size = ethernet_header_compression_configuration->length + sizeof(ethernet_header_compression_configuration->length);
@@ -4669,7 +5264,14 @@ int ogs_nas_5gs_encode_always_on_pdu_session_indication(ogs_pkbuf_t *pkbuf, ogs_
int ogs_nas_5gs_decode_requested_mbs_container(ogs_nas_requested_mbs_container_t *requested_mbs_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_requested_mbs_container_t *source = (ogs_nas_requested_mbs_container_t *)pkbuf->data;
+ ogs_nas_requested_mbs_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_requested_mbs_container_t *)pkbuf->data;
requested_mbs_container->length = be16toh(source->length);
size = requested_mbs_container->length + sizeof(requested_mbs_container->length);
@@ -4715,7 +5317,14 @@ int ogs_nas_5gs_encode_requested_mbs_container(ogs_pkbuf_t *pkbuf, ogs_nas_reque
int ogs_nas_5gs_decode_received_mbs_container(ogs_nas_received_mbs_container_t *received_mbs_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_received_mbs_container_t *source = (ogs_nas_received_mbs_container_t *)pkbuf->data;
+ ogs_nas_received_mbs_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_received_mbs_container_t *)pkbuf->data;
received_mbs_container->length = be16toh(source->length);
size = received_mbs_container->length + sizeof(received_mbs_container->length);
@@ -4761,7 +5370,14 @@ int ogs_nas_5gs_encode_received_mbs_container(ogs_pkbuf_t *pkbuf, ogs_nas_receiv
int ogs_nas_5gs_decode_pdu_session_pair_id(ogs_nas_pdu_session_pair_id_t *pdu_session_pair_id, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdu_session_pair_id_t *source = (ogs_nas_pdu_session_pair_id_t *)pkbuf->data;
+ ogs_nas_pdu_session_pair_id_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdu_session_pair_id_t *)pkbuf->data;
pdu_session_pair_id->length = source->length;
size = pdu_session_pair_id->length + sizeof(pdu_session_pair_id->length);
@@ -4800,7 +5416,14 @@ int ogs_nas_5gs_encode_pdu_session_pair_id(ogs_pkbuf_t *pkbuf, ogs_nas_pdu_sessi
int ogs_nas_5gs_decode_rsn(ogs_nas_rsn_t *rsn, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_rsn_t *source = (ogs_nas_rsn_t *)pkbuf->data;
+ ogs_nas_rsn_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_rsn_t *)pkbuf->data;
rsn->length = source->length;
size = rsn->length + sizeof(rsn->length);
@@ -4903,7 +5526,14 @@ int ogs_nas_5gs_encode_allowed_ssc_mode(ogs_pkbuf_t *pkbuf, ogs_nas_allowed_ssc_
int ogs_nas_5gs_decode_extended_protocol_configuration_options(ogs_nas_extended_protocol_configuration_options_t *extended_protocol_configuration_options, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_protocol_configuration_options_t *source = (ogs_nas_extended_protocol_configuration_options_t *)pkbuf->data;
+ ogs_nas_extended_protocol_configuration_options_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_protocol_configuration_options_t *)pkbuf->data;
extended_protocol_configuration_options->length = be16toh(source->length);
size = extended_protocol_configuration_options->length + sizeof(extended_protocol_configuration_options->length);
@@ -4983,7 +5613,14 @@ int ogs_nas_5gs_encode_integrity_protection_maximum_data_rate(ogs_pkbuf_t *pkbuf
int ogs_nas_5gs_decode_mapped_eps_bearer_contexts(ogs_nas_mapped_eps_bearer_contexts_t *mapped_eps_bearer_contexts, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mapped_eps_bearer_contexts_t *source = (ogs_nas_mapped_eps_bearer_contexts_t *)pkbuf->data;
+ ogs_nas_mapped_eps_bearer_contexts_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mapped_eps_bearer_contexts_t *)pkbuf->data;
mapped_eps_bearer_contexts->length = be16toh(source->length);
size = mapped_eps_bearer_contexts->length + sizeof(mapped_eps_bearer_contexts->length);
diff --git a/lib/nas/5gs/support/nas-message.py b/lib/nas/5gs/support/nas-message.py
index 24d1053fd..42e33cd26 100644
--- a/lib/nas/5gs/support/nas-message.py
+++ b/lib/nas/5gs/support/nas-message.py
@@ -447,7 +447,12 @@ for (k, v) in sorted_type_list:
f.write("int ogs_nas_5gs_decode_%s(ogs_nas_%s_t *%s, ogs_pkbuf_t *pkbuf)\n" % (v_lower(k), v_lower(k), get_value(k)))
f.write("{\n")
f.write(" int size = 0;\n")
- f.write(" ogs_nas_%s_t *source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % (v_lower(k), v_lower(k)))
+ f.write(" ogs_nas_%s_t *source = NULL;\n\n" % v_lower(k))
+ f.write(" if (pkbuf->len < 2) {\n")
+ f.write(" ogs_error(\"Not enough pkbuf [len:%d]\", pkbuf->len);\n")
+ f.write(" return -1;\n")
+ f.write(" }\n\n")
+ f.write(" source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % v_lower(k))
f.write(" %s->length = be16toh(source->length);\n" % get_value(k))
f.write(" size = %s->length + sizeof(%s->length);\n\n" % (get_value(k), get_value(k)))
f.write(" if (ogs_pkbuf_pull(pkbuf, size) == NULL) {\n")
@@ -480,7 +485,12 @@ for (k, v) in sorted_type_list:
f.write("int ogs_nas_5gs_decode_%s(ogs_nas_%s_t *%s, ogs_pkbuf_t *pkbuf)\n" % (v_lower(k), v_lower(k), get_value(k)))
f.write("{\n")
f.write(" int size = 0;\n")
- f.write(" ogs_nas_%s_t *source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % (v_lower(k), v_lower(k)))
+ f.write(" ogs_nas_%s_t *source = NULL;\n\n" % v_lower(k))
+ f.write(" if (pkbuf->len < 1) {\n")
+ f.write(" ogs_error(\"Not enough pkbuf [len:%d]\", pkbuf->len);\n")
+ f.write(" return -1;\n")
+ f.write(" }\n\n")
+ f.write(" source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % v_lower(k))
f.write(" %s->length = source->length;\n" % get_value(k))
f.write(" size = %s->length + sizeof(%s->length);\n\n" % (get_value(k), get_value(k)))
f.write(" if (ogs_pkbuf_pull(pkbuf, size) == NULL) {\n")
diff --git a/lib/nas/5gs/types.c b/lib/nas/5gs/types.c
index f8a049deb..5e65c0942 100644
--- a/lib/nas/5gs/types.c
+++ b/lib/nas/5gs/types.c
@@ -128,8 +128,7 @@ void ogs_nas_build_s_nssai(
pos = 0;
- if (nas_s_nssai_ie->sst)
- nas_s_nssai->buffer[pos++] = nas_s_nssai_ie->sst;
+ nas_s_nssai->buffer[pos++] = nas_s_nssai_ie->sst;
if (nas_s_nssai_ie->sd.v != OGS_S_NSSAI_NO_SD_VALUE ||
@@ -141,7 +140,7 @@ void ogs_nas_build_s_nssai(
* "no SD value associated with the SST".
*/
(nas_s_nssai_ie->sd.v == OGS_S_NSSAI_NO_SD_VALUE &&
- nas_s_nssai_ie->mapped_hplmn_sst &&
+ nas_s_nssai_ie->mapped_hplmn_sst_presence &&
nas_s_nssai_ie->mapped_hplmn_sd.v != OGS_S_NSSAI_NO_SD_VALUE)) {
v = ogs_htobe24(nas_s_nssai_ie->sd);
@@ -149,7 +148,7 @@ void ogs_nas_build_s_nssai(
pos += 3;
}
- if (nas_s_nssai_ie->mapped_hplmn_sst)
+ if (nas_s_nssai_ie->mapped_hplmn_sst_presence)
nas_s_nssai->buffer[pos++] = nas_s_nssai_ie->mapped_hplmn_sst;
if (nas_s_nssai_ie->mapped_hplmn_sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
@@ -169,14 +168,19 @@ void ogs_nas_build_s_nssai2(
ogs_assert(nas_s_nssai);
ogs_assert(s_nssai);
- ogs_assert(mapped_hplmn);
memset(&ie, 0, sizeof(ie));
ie.sst = s_nssai->sst;
ie.sd.v = s_nssai->sd.v;
- ie.mapped_hplmn_sst = mapped_hplmn->sst;
- ie.mapped_hplmn_sd.v = mapped_hplmn->sd.v;
+
+ if (mapped_hplmn) {
+ ie.mapped_hplmn_sst_presence = true;
+ ie.mapped_hplmn_sst = mapped_hplmn->sst;
+ ie.mapped_hplmn_sd.v = mapped_hplmn->sd.v;
+ } else {
+ ie.mapped_hplmn_sd.v = OGS_S_NSSAI_NO_SD_VALUE;
+ }
ogs_nas_build_s_nssai(nas_s_nssai, &ie);
}
@@ -240,8 +244,10 @@ int ogs_nas_parse_s_nssai(
pos += 3;
}
- if (mapped_hplmn_sst)
+ if (mapped_hplmn_sst) {
nas_s_nssai_ie->mapped_hplmn_sst = nas_s_nssai->buffer[pos++];
+ nas_s_nssai_ie->mapped_hplmn_sst_presence = true;
+ }
if (mapped_hplmn_sd) {
memcpy(&v, nas_s_nssai->buffer+pos, 3);
diff --git a/lib/nas/5gs/types.h b/lib/nas/5gs/types.h
index b7ff296ad..b20e7b588 100644
--- a/lib/nas/5gs/types.h
+++ b/lib/nas/5gs/types.h
@@ -66,6 +66,7 @@ typedef struct ogs_nas_s_nssai_ie_s {
uint8_t sst;
ogs_uint24_t sd;
uint8_t mapped_hplmn_sst;
+ bool mapped_hplmn_sst_presence;
ogs_uint24_t mapped_hplmn_sd;
} __attribute__ ((packed)) ogs_nas_s_nssai_ie_t;
@@ -1052,7 +1053,7 @@ typedef struct ogs_nas_qos_rule_s {
struct {
ED3(uint8_t spare:1;,
uint8_t segregation:1;,
- uint8_t identifier:4;)
+ uint8_t identifier:6;)
};
uint8_t flags;
} flow;
diff --git a/lib/nas/eps/ies.c b/lib/nas/eps/ies.c
index 8144341b8..8a221d761 100644
--- a/lib/nas/eps/ies.c
+++ b/lib/nas/eps/ies.c
@@ -28,7 +28,7 @@
/*******************************************************************************
* This file had been created by nas-message.py script v0.1.0
* Please do not modify this file but regenerate it via script.
- * Created on: 2024-01-21 18:50:03.402793 by acetcom
+ * Created on: 2024-12-11 21:08:02.462921 by acetcom
* from 24301-h90.docx
******************************************************************************/
@@ -48,7 +48,14 @@ int ogs_nas_eps_encode_optional_type(ogs_pkbuf_t *pkbuf, uint8_t type)
int ogs_nas_eps_decode_additional_information(ogs_nas_additional_information_t *additional_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_additional_information_t *source = (ogs_nas_additional_information_t *)pkbuf->data;
+ ogs_nas_additional_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_additional_information_t *)pkbuf->data;
additional_information->length = source->length;
size = additional_information->length + sizeof(additional_information->length);
@@ -119,7 +126,14 @@ int ogs_nas_eps_encode_device_properties(ogs_pkbuf_t *pkbuf, ogs_nas_device_prop
int ogs_nas_eps_decode_eps_bearer_context_status(ogs_nas_eps_bearer_context_status_t *eps_bearer_context_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_bearer_context_status_t *source = (ogs_nas_eps_bearer_context_status_t *)pkbuf->data;
+ ogs_nas_eps_bearer_context_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_bearer_context_status_t *)pkbuf->data;
eps_bearer_context_status->length = source->length;
size = eps_bearer_context_status->length + sizeof(eps_bearer_context_status->length);
@@ -158,7 +172,14 @@ int ogs_nas_eps_encode_eps_bearer_context_status(ogs_pkbuf_t *pkbuf, ogs_nas_eps
int ogs_nas_eps_decode_supported_codec_list(ogs_nas_supported_codec_list_t *supported_codec_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_supported_codec_list_t *source = (ogs_nas_supported_codec_list_t *)pkbuf->data;
+ ogs_nas_supported_codec_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_supported_codec_list_t *)pkbuf->data;
supported_codec_list->length = source->length;
size = supported_codec_list->length + sizeof(supported_codec_list->length);
@@ -235,7 +256,14 @@ int ogs_nas_eps_encode_location_area_identification(ogs_pkbuf_t *pkbuf, ogs_nas_
int ogs_nas_eps_decode_mobile_identity(ogs_nas_mobile_identity_t *mobile_identity, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mobile_identity_t *source = (ogs_nas_mobile_identity_t *)pkbuf->data;
+ ogs_nas_mobile_identity_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mobile_identity_t *)pkbuf->data;
mobile_identity->length = source->length;
size = mobile_identity->length + sizeof(mobile_identity->length);
@@ -283,7 +311,14 @@ int ogs_nas_eps_encode_mobile_identity(ogs_pkbuf_t *pkbuf, ogs_nas_mobile_identi
int ogs_nas_eps_decode_mobile_station_classmark_2(ogs_nas_mobile_station_classmark_2_t *mobile_station_classmark_2, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mobile_station_classmark_2_t *source = (ogs_nas_mobile_station_classmark_2_t *)pkbuf->data;
+ ogs_nas_mobile_station_classmark_2_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mobile_station_classmark_2_t *)pkbuf->data;
mobile_station_classmark_2->length = source->length;
size = mobile_station_classmark_2->length + sizeof(mobile_station_classmark_2->length);
@@ -322,7 +357,14 @@ int ogs_nas_eps_encode_mobile_station_classmark_2(ogs_pkbuf_t *pkbuf, ogs_nas_mo
int ogs_nas_eps_decode_mobile_station_classmark_3(ogs_nas_mobile_station_classmark_3_t *mobile_station_classmark_3, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_mobile_station_classmark_3_t *source = (ogs_nas_mobile_station_classmark_3_t *)pkbuf->data;
+ ogs_nas_mobile_station_classmark_3_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_mobile_station_classmark_3_t *)pkbuf->data;
mobile_station_classmark_3->length = source->length;
size = mobile_station_classmark_3->length + sizeof(mobile_station_classmark_3->length);
@@ -361,7 +403,14 @@ int ogs_nas_eps_encode_mobile_station_classmark_3(ogs_pkbuf_t *pkbuf, ogs_nas_mo
int ogs_nas_eps_decode_plmn_list(ogs_nas_plmn_list_t *plmn_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_plmn_list_t *source = (ogs_nas_plmn_list_t *)pkbuf->data;
+ ogs_nas_plmn_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_plmn_list_t *)pkbuf->data;
plmn_list->length = source->length;
size = plmn_list->length + sizeof(plmn_list->length);
@@ -464,7 +513,14 @@ int ogs_nas_eps_encode_additional_update_type(ogs_pkbuf_t *pkbuf, ogs_nas_additi
int ogs_nas_eps_decode_authentication_failure_parameter(ogs_nas_authentication_failure_parameter_t *authentication_failure_parameter, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_failure_parameter_t *source = (ogs_nas_authentication_failure_parameter_t *)pkbuf->data;
+ ogs_nas_authentication_failure_parameter_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_failure_parameter_t *)pkbuf->data;
authentication_failure_parameter->length = source->length;
size = authentication_failure_parameter->length + sizeof(authentication_failure_parameter->length);
@@ -571,7 +627,14 @@ int ogs_nas_eps_encode_eps_attach_type(ogs_pkbuf_t *pkbuf, ogs_nas_eps_attach_ty
int ogs_nas_eps_decode_eps_mobile_identity(ogs_nas_eps_mobile_identity_t *eps_mobile_identity, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_mobile_identity_t *source = (ogs_nas_eps_mobile_identity_t *)pkbuf->data;
+ ogs_nas_eps_mobile_identity_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_mobile_identity_t *)pkbuf->data;
eps_mobile_identity->length = source->length;
size = eps_mobile_identity->length + sizeof(eps_mobile_identity->length);
@@ -621,7 +684,14 @@ int ogs_nas_eps_encode_eps_mobile_identity(ogs_pkbuf_t *pkbuf, ogs_nas_eps_mobil
int ogs_nas_eps_decode_eps_network_feature_support(ogs_nas_eps_network_feature_support_t *eps_network_feature_support, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_network_feature_support_t *source = (ogs_nas_eps_network_feature_support_t *)pkbuf->data;
+ ogs_nas_eps_network_feature_support_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_network_feature_support_t *)pkbuf->data;
eps_network_feature_support->length = source->length;
size = eps_network_feature_support->length + sizeof(eps_network_feature_support->length);
@@ -728,7 +798,14 @@ int ogs_nas_eps_encode_eps_update_type(ogs_pkbuf_t *pkbuf, ogs_nas_eps_update_ty
int ogs_nas_eps_decode_esm_message_container(ogs_nas_esm_message_container_t *esm_message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_esm_message_container_t *source = (ogs_nas_esm_message_container_t *)pkbuf->data;
+ ogs_nas_esm_message_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_esm_message_container_t *)pkbuf->data;
esm_message_container->length = be16toh(source->length);
size = esm_message_container->length + sizeof(esm_message_container->length);
@@ -808,7 +885,14 @@ int ogs_nas_eps_encode_gprs_timer(ogs_pkbuf_t *pkbuf, ogs_nas_gprs_timer_t *gprs
int ogs_nas_eps_decode_gprs_timer_2(ogs_nas_gprs_timer_2_t *gprs_timer_2, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_gprs_timer_2_t *source = (ogs_nas_gprs_timer_2_t *)pkbuf->data;
+ ogs_nas_gprs_timer_2_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_gprs_timer_2_t *)pkbuf->data;
gprs_timer_2->length = source->length;
size = gprs_timer_2->length + sizeof(gprs_timer_2->length);
@@ -847,7 +931,14 @@ int ogs_nas_eps_encode_gprs_timer_2(ogs_pkbuf_t *pkbuf, ogs_nas_gprs_timer_2_t *
int ogs_nas_eps_decode_gprs_timer_3(ogs_nas_gprs_timer_3_t *gprs_timer_3, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_gprs_timer_3_t *source = (ogs_nas_gprs_timer_3_t *)pkbuf->data;
+ ogs_nas_gprs_timer_3_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_gprs_timer_3_t *)pkbuf->data;
gprs_timer_3->length = source->length;
size = gprs_timer_3->length + sizeof(gprs_timer_3->length);
@@ -986,7 +1077,14 @@ int ogs_nas_eps_encode_ksi_and_sequence_number(ogs_pkbuf_t *pkbuf, ogs_nas_ksi_a
int ogs_nas_eps_decode_authentication_parameter_autn(ogs_nas_authentication_parameter_autn_t *authentication_parameter_autn, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_parameter_autn_t *source = (ogs_nas_authentication_parameter_autn_t *)pkbuf->data;
+ ogs_nas_authentication_parameter_autn_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_parameter_autn_t *)pkbuf->data;
authentication_parameter_autn->length = source->length;
size = authentication_parameter_autn->length + sizeof(authentication_parameter_autn->length);
@@ -1025,7 +1123,14 @@ int ogs_nas_eps_encode_authentication_parameter_autn(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_eps_decode_ms_network_capability(ogs_nas_ms_network_capability_t *ms_network_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ms_network_capability_t *source = (ogs_nas_ms_network_capability_t *)pkbuf->data;
+ ogs_nas_ms_network_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ms_network_capability_t *)pkbuf->data;
ms_network_capability->length = source->length;
size = ms_network_capability->length + sizeof(ms_network_capability->length);
@@ -1128,7 +1233,14 @@ int ogs_nas_eps_encode_key_set_identifier(ogs_pkbuf_t *pkbuf, ogs_nas_key_set_id
int ogs_nas_eps_decode_eps_message_container(ogs_nas_eps_message_container_t *eps_message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_message_container_t *source = (ogs_nas_eps_message_container_t *)pkbuf->data;
+ ogs_nas_eps_message_container_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_message_container_t *)pkbuf->data;
eps_message_container->length = source->length;
size = eps_message_container->length + sizeof(eps_message_container->length);
@@ -1201,7 +1313,14 @@ int ogs_nas_eps_encode_security_algorithms(ogs_pkbuf_t *pkbuf, ogs_nas_security_
int ogs_nas_eps_decode_network_name(ogs_nas_network_name_t *network_name, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_network_name_t *source = (ogs_nas_network_name_t *)pkbuf->data;
+ ogs_nas_network_name_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_network_name_t *)pkbuf->data;
network_name->length = source->length;
size = network_name->length + sizeof(network_name->length);
@@ -1240,7 +1359,14 @@ int ogs_nas_eps_encode_network_name(ogs_pkbuf_t *pkbuf, ogs_nas_network_name_t *
int ogs_nas_eps_decode_network_resource_identifier_container(ogs_nas_network_resource_identifier_container_t *network_resource_identifier_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_network_resource_identifier_container_t *source = (ogs_nas_network_resource_identifier_container_t *)pkbuf->data;
+ ogs_nas_network_resource_identifier_container_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_network_resource_identifier_container_t *)pkbuf->data;
network_resource_identifier_container->length = source->length;
size = network_resource_identifier_container->length + sizeof(network_resource_identifier_container->length);
@@ -1665,7 +1791,14 @@ int ogs_nas_eps_encode_tracking_area_identity(ogs_pkbuf_t *pkbuf, ogs_nas_tracki
int ogs_nas_eps_decode_tracking_area_identity_list(ogs_nas_tracking_area_identity_list_t *tracking_area_identity_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_tracking_area_identity_list_t *source = (ogs_nas_tracking_area_identity_list_t *)pkbuf->data;
+ ogs_nas_tracking_area_identity_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_tracking_area_identity_list_t *)pkbuf->data;
tracking_area_identity_list->length = source->length;
size = tracking_area_identity_list->length + sizeof(tracking_area_identity_list->length);
@@ -1704,7 +1837,14 @@ int ogs_nas_eps_encode_tracking_area_identity_list(ogs_pkbuf_t *pkbuf, ogs_nas_t
int ogs_nas_eps_decode_ue_network_capability(ogs_nas_ue_network_capability_t *ue_network_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_network_capability_t *source = (ogs_nas_ue_network_capability_t *)pkbuf->data;
+ ogs_nas_ue_network_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_network_capability_t *)pkbuf->data;
ue_network_capability->length = source->length;
size = ue_network_capability->length + sizeof(ue_network_capability->length);
@@ -1775,7 +1915,14 @@ int ogs_nas_eps_encode_ue_radio_capability_information_update_needed(ogs_pkbuf_t
int ogs_nas_eps_decode_ue_security_capability(ogs_nas_ue_security_capability_t *ue_security_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_security_capability_t *source = (ogs_nas_ue_security_capability_t *)pkbuf->data;
+ ogs_nas_ue_security_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_security_capability_t *)pkbuf->data;
ue_security_capability->length = source->length;
size = ue_security_capability->length + sizeof(ue_security_capability->length);
@@ -1814,7 +1961,14 @@ int ogs_nas_eps_encode_ue_security_capability(ogs_pkbuf_t *pkbuf, ogs_nas_ue_sec
int ogs_nas_eps_decode_emergency_number_list(ogs_nas_emergency_number_list_t *emergency_number_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_emergency_number_list_t *source = (ogs_nas_emergency_number_list_t *)pkbuf->data;
+ ogs_nas_emergency_number_list_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_emergency_number_list_t *)pkbuf->data;
emergency_number_list->length = source->length;
size = emergency_number_list->length + sizeof(emergency_number_list->length);
@@ -1853,7 +2007,14 @@ int ogs_nas_eps_encode_emergency_number_list(ogs_pkbuf_t *pkbuf, ogs_nas_emergen
int ogs_nas_eps_decode_extended_emergency_number_list(ogs_nas_extended_emergency_number_list_t *extended_emergency_number_list, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_emergency_number_list_t *source = (ogs_nas_extended_emergency_number_list_t *)pkbuf->data;
+ ogs_nas_extended_emergency_number_list_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_emergency_number_list_t *)pkbuf->data;
extended_emergency_number_list->length = be16toh(source->length);
size = extended_emergency_number_list->length + sizeof(extended_emergency_number_list->length);
@@ -1899,7 +2060,14 @@ int ogs_nas_eps_encode_extended_emergency_number_list(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_eps_decode_cli(ogs_nas_cli_t *cli, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_cli_t *source = (ogs_nas_cli_t *)pkbuf->data;
+ ogs_nas_cli_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_cli_t *)pkbuf->data;
cli->length = source->length;
size = cli->length + sizeof(cli->length);
@@ -1972,7 +2140,14 @@ int ogs_nas_eps_encode_ss_code(ogs_pkbuf_t *pkbuf, ogs_nas_ss_code_t *ss_code)
int ogs_nas_eps_decode_authentication_response_parameter(ogs_nas_authentication_response_parameter_t *authentication_response_parameter, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_authentication_response_parameter_t *source = (ogs_nas_authentication_response_parameter_t *)pkbuf->data;
+ ogs_nas_authentication_response_parameter_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_authentication_response_parameter_t *)pkbuf->data;
authentication_response_parameter->length = source->length;
size = authentication_response_parameter->length + sizeof(authentication_response_parameter->length);
@@ -2045,7 +2220,14 @@ int ogs_nas_eps_encode_lcs_indicator(ogs_pkbuf_t *pkbuf, ogs_nas_lcs_indicator_t
int ogs_nas_eps_decode_lcs_client_identity(ogs_nas_lcs_client_identity_t *lcs_client_identity, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_lcs_client_identity_t *source = (ogs_nas_lcs_client_identity_t *)pkbuf->data;
+ ogs_nas_lcs_client_identity_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_lcs_client_identity_t *)pkbuf->data;
lcs_client_identity->length = source->length;
size = lcs_client_identity->length + sizeof(lcs_client_identity->length);
@@ -2118,7 +2300,14 @@ int ogs_nas_eps_encode_generic_message_container_type(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_eps_decode_generic_message_container(ogs_nas_generic_message_container_t *generic_message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_generic_message_container_t *source = (ogs_nas_generic_message_container_t *)pkbuf->data;
+ ogs_nas_generic_message_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_generic_message_container_t *)pkbuf->data;
generic_message_container->length = be16toh(source->length);
size = generic_message_container->length + sizeof(generic_message_container->length);
@@ -2164,7 +2353,14 @@ int ogs_nas_eps_encode_generic_message_container(ogs_pkbuf_t *pkbuf, ogs_nas_gen
int ogs_nas_eps_decode_voice_domain_preference_and_ue_usage_setting(ogs_nas_voice_domain_preference_and_ue_usage_setting_t *voice_domain_preference_and_ue_usage_setting, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_voice_domain_preference_and_ue_usage_setting_t *source = (ogs_nas_voice_domain_preference_and_ue_usage_setting_t *)pkbuf->data;
+ ogs_nas_voice_domain_preference_and_ue_usage_setting_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_voice_domain_preference_and_ue_usage_setting_t *)pkbuf->data;
voice_domain_preference_and_ue_usage_setting->length = source->length;
size = voice_domain_preference_and_ue_usage_setting->length + sizeof(voice_domain_preference_and_ue_usage_setting->length);
@@ -2235,7 +2431,14 @@ int ogs_nas_eps_encode_guti_type(ogs_pkbuf_t *pkbuf, ogs_nas_guti_type_t *guti_t
int ogs_nas_eps_decode_extended_drx_parameters(ogs_nas_extended_drx_parameters_t *extended_drx_parameters, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_drx_parameters_t *source = (ogs_nas_extended_drx_parameters_t *)pkbuf->data;
+ ogs_nas_extended_drx_parameters_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_drx_parameters_t *)pkbuf->data;
extended_drx_parameters->length = source->length;
size = extended_drx_parameters->length + sizeof(extended_drx_parameters->length);
@@ -2274,7 +2477,14 @@ int ogs_nas_eps_encode_extended_drx_parameters(ogs_pkbuf_t *pkbuf, ogs_nas_exten
int ogs_nas_eps_decode_dcn_id(ogs_nas_dcn_id_t *dcn_id, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_dcn_id_t *source = (ogs_nas_dcn_id_t *)pkbuf->data;
+ ogs_nas_dcn_id_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_dcn_id_t *)pkbuf->data;
dcn_id->length = source->length;
size = dcn_id->length + sizeof(dcn_id->length);
@@ -2441,7 +2651,14 @@ int ogs_nas_eps_encode_csfb_response(ogs_pkbuf_t *pkbuf, ogs_nas_csfb_response_t
int ogs_nas_eps_decode_hashmme(ogs_nas_hashmme_t *hashmme, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_hashmme_t *source = (ogs_nas_hashmme_t *)pkbuf->data;
+ ogs_nas_hashmme_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_hashmme_t *)pkbuf->data;
hashmme->length = source->length;
size = hashmme->length + sizeof(hashmme->length);
@@ -2480,7 +2697,14 @@ int ogs_nas_eps_encode_hashmme(ogs_pkbuf_t *pkbuf, ogs_nas_hashmme_t *hashmme)
int ogs_nas_eps_decode_replayed_nas_message_container(ogs_nas_replayed_nas_message_container_t *replayed_nas_message_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_replayed_nas_message_container_t *source = (ogs_nas_replayed_nas_message_container_t *)pkbuf->data;
+ ogs_nas_replayed_nas_message_container_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_replayed_nas_message_container_t *)pkbuf->data;
replayed_nas_message_container->length = be16toh(source->length);
size = replayed_nas_message_container->length + sizeof(replayed_nas_message_container->length);
@@ -2558,7 +2782,14 @@ int ogs_nas_eps_encode_network_policy(ogs_pkbuf_t *pkbuf, ogs_nas_network_policy
int ogs_nas_eps_decode_ue_additional_security_capability(ogs_nas_ue_additional_security_capability_t *ue_additional_security_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_additional_security_capability_t *source = (ogs_nas_ue_additional_security_capability_t *)pkbuf->data;
+ ogs_nas_ue_additional_security_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_additional_security_capability_t *)pkbuf->data;
ue_additional_security_capability->length = source->length;
size = ue_additional_security_capability->length + sizeof(ue_additional_security_capability->length);
@@ -2597,7 +2828,14 @@ int ogs_nas_eps_encode_ue_additional_security_capability(ogs_pkbuf_t *pkbuf, ogs
int ogs_nas_eps_decode_ue_status(ogs_nas_ue_status_t *ue_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_status_t *source = (ogs_nas_ue_status_t *)pkbuf->data;
+ ogs_nas_ue_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_status_t *)pkbuf->data;
ue_status->length = source->length;
size = ue_status->length + sizeof(ue_status->length);
@@ -2670,7 +2908,14 @@ int ogs_nas_eps_encode_additional_information_requested(ogs_pkbuf_t *pkbuf, ogs_
int ogs_nas_eps_decode_ciphering_key_data(ogs_nas_ciphering_key_data_t *ciphering_key_data, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ciphering_key_data_t *source = (ogs_nas_ciphering_key_data_t *)pkbuf->data;
+ ogs_nas_ciphering_key_data_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ciphering_key_data_t *)pkbuf->data;
ciphering_key_data->length = be16toh(source->length);
size = ciphering_key_data->length + sizeof(ciphering_key_data->length);
@@ -2716,7 +2961,14 @@ int ogs_nas_eps_encode_ciphering_key_data(ogs_pkbuf_t *pkbuf, ogs_nas_ciphering_
int ogs_nas_eps_decode_n1_ue_network_capability(ogs_nas_n1_ue_network_capability_t *n1_ue_network_capability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_n1_ue_network_capability_t *source = (ogs_nas_n1_ue_network_capability_t *)pkbuf->data;
+ ogs_nas_n1_ue_network_capability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_n1_ue_network_capability_t *)pkbuf->data;
n1_ue_network_capability->length = source->length;
size = n1_ue_network_capability->length + sizeof(n1_ue_network_capability->length);
@@ -2755,7 +3007,14 @@ int ogs_nas_eps_encode_n1_ue_network_capability(ogs_pkbuf_t *pkbuf, ogs_nas_n1_u
int ogs_nas_eps_decode_ue_radio_capability_id_availability(ogs_nas_ue_radio_capability_id_availability_t *ue_radio_capability_id_availability, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_radio_capability_id_availability_t *source = (ogs_nas_ue_radio_capability_id_availability_t *)pkbuf->data;
+ ogs_nas_ue_radio_capability_id_availability_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_radio_capability_id_availability_t *)pkbuf->data;
ue_radio_capability_id_availability->length = source->length;
size = ue_radio_capability_id_availability->length + sizeof(ue_radio_capability_id_availability->length);
@@ -2794,7 +3053,14 @@ int ogs_nas_eps_encode_ue_radio_capability_id_availability(ogs_pkbuf_t *pkbuf, o
int ogs_nas_eps_decode_ue_radio_capability_id_request(ogs_nas_ue_radio_capability_id_request_t *ue_radio_capability_id_request, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_radio_capability_id_request_t *source = (ogs_nas_ue_radio_capability_id_request_t *)pkbuf->data;
+ ogs_nas_ue_radio_capability_id_request_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_radio_capability_id_request_t *)pkbuf->data;
ue_radio_capability_id_request->length = source->length;
size = ue_radio_capability_id_request->length + sizeof(ue_radio_capability_id_request->length);
@@ -2833,7 +3099,14 @@ int ogs_nas_eps_encode_ue_radio_capability_id_request(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_eps_decode_daylight_saving_time(ogs_nas_daylight_saving_time_t *daylight_saving_time, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_daylight_saving_time_t *source = (ogs_nas_daylight_saving_time_t *)pkbuf->data;
+ ogs_nas_daylight_saving_time_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_daylight_saving_time_t *)pkbuf->data;
daylight_saving_time->length = source->length;
size = daylight_saving_time->length + sizeof(daylight_saving_time->length);
@@ -2872,7 +3145,14 @@ int ogs_nas_eps_encode_daylight_saving_time(ogs_pkbuf_t *pkbuf, ogs_nas_daylight
int ogs_nas_eps_decode_ue_radio_capability_id(ogs_nas_ue_radio_capability_id_t *ue_radio_capability_id, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_radio_capability_id_t *source = (ogs_nas_ue_radio_capability_id_t *)pkbuf->data;
+ ogs_nas_ue_radio_capability_id_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_radio_capability_id_t *)pkbuf->data;
ue_radio_capability_id->length = source->length;
size = ue_radio_capability_id->length + sizeof(ue_radio_capability_id->length);
@@ -2943,7 +3223,14 @@ int ogs_nas_eps_encode_ue_radio_capability_id_deletion_indication(ogs_pkbuf_t *p
int ogs_nas_eps_decode_wus_assistance_information(ogs_nas_wus_assistance_information_t *wus_assistance_information, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_wus_assistance_information_t *source = (ogs_nas_wus_assistance_information_t *)pkbuf->data;
+ ogs_nas_wus_assistance_information_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_wus_assistance_information_t *)pkbuf->data;
wus_assistance_information->length = source->length;
size = wus_assistance_information->length + sizeof(wus_assistance_information->length);
@@ -2982,7 +3269,14 @@ int ogs_nas_eps_encode_wus_assistance_information(ogs_pkbuf_t *pkbuf, ogs_nas_wu
int ogs_nas_eps_decode_nb_s1_drx_parameter(ogs_nas_nb_s1_drx_parameter_t *nb_s1_drx_parameter, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nb_s1_drx_parameter_t *source = (ogs_nas_nb_s1_drx_parameter_t *)pkbuf->data;
+ ogs_nas_nb_s1_drx_parameter_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nb_s1_drx_parameter_t *)pkbuf->data;
nb_s1_drx_parameter->length = source->length;
size = nb_s1_drx_parameter->length + sizeof(nb_s1_drx_parameter->length);
@@ -3021,7 +3315,14 @@ int ogs_nas_eps_encode_nb_s1_drx_parameter(ogs_pkbuf_t *pkbuf, ogs_nas_nb_s1_drx
int ogs_nas_eps_decode_imsi_offset(ogs_nas_imsi_offset_t *imsi_offset, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_imsi_offset_t *source = (ogs_nas_imsi_offset_t *)pkbuf->data;
+ ogs_nas_imsi_offset_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_imsi_offset_t *)pkbuf->data;
imsi_offset->length = source->length;
size = imsi_offset->length + sizeof(imsi_offset->length);
@@ -3060,7 +3361,14 @@ int ogs_nas_eps_encode_imsi_offset(ogs_pkbuf_t *pkbuf, ogs_nas_imsi_offset_t *im
int ogs_nas_eps_decode_ue_request_type(ogs_nas_ue_request_type_t *ue_request_type, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_ue_request_type_t *source = (ogs_nas_ue_request_type_t *)pkbuf->data;
+ ogs_nas_ue_request_type_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_ue_request_type_t *)pkbuf->data;
ue_request_type->length = source->length;
size = ue_request_type->length + sizeof(ue_request_type->length);
@@ -3099,7 +3407,14 @@ int ogs_nas_eps_encode_ue_request_type(ogs_pkbuf_t *pkbuf, ogs_nas_ue_request_ty
int ogs_nas_eps_decode_paging_restriction(ogs_nas_paging_restriction_t *paging_restriction, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_paging_restriction_t *source = (ogs_nas_paging_restriction_t *)pkbuf->data;
+ ogs_nas_paging_restriction_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_paging_restriction_t *)pkbuf->data;
paging_restriction->length = source->length;
size = paging_restriction->length + sizeof(paging_restriction->length);
@@ -3138,7 +3453,14 @@ int ogs_nas_eps_encode_paging_restriction(ogs_pkbuf_t *pkbuf, ogs_nas_paging_res
int ogs_nas_eps_decode_eps_additional_request_result(ogs_nas_eps_additional_request_result_t *eps_additional_request_result, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_additional_request_result_t *source = (ogs_nas_eps_additional_request_result_t *)pkbuf->data;
+ ogs_nas_eps_additional_request_result_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_additional_request_result_t *)pkbuf->data;
eps_additional_request_result->length = source->length;
size = eps_additional_request_result->length + sizeof(eps_additional_request_result->length);
@@ -3279,7 +3601,14 @@ int ogs_nas_eps_encode_emm_cause(ogs_pkbuf_t *pkbuf, ogs_nas_emm_cause_t *emm_ca
int ogs_nas_eps_decode_access_point_name(ogs_nas_access_point_name_t *access_point_name, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_access_point_name_t *source = (ogs_nas_access_point_name_t *)pkbuf->data;
+ ogs_nas_access_point_name_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_access_point_name_t *)pkbuf->data;
access_point_name->length = source->length;
size = access_point_name->length + sizeof(access_point_name->length);
@@ -3331,7 +3660,14 @@ int ogs_nas_eps_encode_access_point_name(ogs_pkbuf_t *pkbuf, ogs_nas_access_poin
int ogs_nas_eps_decode_protocol_configuration_options(ogs_nas_protocol_configuration_options_t *protocol_configuration_options, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_protocol_configuration_options_t *source = (ogs_nas_protocol_configuration_options_t *)pkbuf->data;
+ ogs_nas_protocol_configuration_options_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_protocol_configuration_options_t *)pkbuf->data;
protocol_configuration_options->length = source->length;
size = protocol_configuration_options->length + sizeof(protocol_configuration_options->length);
@@ -3370,7 +3706,14 @@ int ogs_nas_eps_encode_protocol_configuration_options(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_eps_decode_quality_of_service(ogs_nas_quality_of_service_t *quality_of_service, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_quality_of_service_t *source = (ogs_nas_quality_of_service_t *)pkbuf->data;
+ ogs_nas_quality_of_service_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_quality_of_service_t *)pkbuf->data;
quality_of_service->length = source->length;
size = quality_of_service->length + sizeof(quality_of_service->length);
@@ -3441,7 +3784,14 @@ int ogs_nas_eps_encode_radio_priority(ogs_pkbuf_t *pkbuf, ogs_nas_radio_priority
int ogs_nas_eps_decode_re_attempt_indicator(ogs_nas_re_attempt_indicator_t *re_attempt_indicator, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_re_attempt_indicator_t *source = (ogs_nas_re_attempt_indicator_t *)pkbuf->data;
+ ogs_nas_re_attempt_indicator_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_re_attempt_indicator_t *)pkbuf->data;
re_attempt_indicator->length = source->length;
size = re_attempt_indicator->length + sizeof(re_attempt_indicator->length);
@@ -3514,7 +3864,14 @@ int ogs_nas_eps_encode_request_type(ogs_pkbuf_t *pkbuf, ogs_nas_request_type_t *
int ogs_nas_eps_decode_traffic_flow_aggregate_description(ogs_nas_traffic_flow_aggregate_description_t *traffic_flow_aggregate_description, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_traffic_flow_aggregate_description_t *source = (ogs_nas_traffic_flow_aggregate_description_t *)pkbuf->data;
+ ogs_nas_traffic_flow_aggregate_description_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_traffic_flow_aggregate_description_t *)pkbuf->data;
traffic_flow_aggregate_description->length = source->length;
size = traffic_flow_aggregate_description->length + sizeof(traffic_flow_aggregate_description->length);
@@ -3553,7 +3910,14 @@ int ogs_nas_eps_encode_traffic_flow_aggregate_description(ogs_pkbuf_t *pkbuf, og
int ogs_nas_eps_decode_traffic_flow_template(ogs_nas_traffic_flow_template_t *traffic_flow_template, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_traffic_flow_template_t *source = (ogs_nas_traffic_flow_template_t *)pkbuf->data;
+ ogs_nas_traffic_flow_template_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_traffic_flow_template_t *)pkbuf->data;
traffic_flow_template->length = source->length;
size = traffic_flow_template->length + sizeof(traffic_flow_template->length);
@@ -3592,7 +3956,14 @@ int ogs_nas_eps_encode_traffic_flow_template(ogs_pkbuf_t *pkbuf, ogs_nas_traffic
int ogs_nas_eps_decode_transaction_identifier(ogs_nas_transaction_identifier_t *transaction_identifier, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_transaction_identifier_t *source = (ogs_nas_transaction_identifier_t *)pkbuf->data;
+ ogs_nas_transaction_identifier_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_transaction_identifier_t *)pkbuf->data;
transaction_identifier->length = source->length;
size = transaction_identifier->length + sizeof(transaction_identifier->length);
@@ -3663,7 +4034,14 @@ int ogs_nas_eps_encode_wlan_offload_acceptability(ogs_pkbuf_t *pkbuf, ogs_nas_wl
int ogs_nas_eps_decode_nbifom_container(ogs_nas_nbifom_container_t *nbifom_container, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_nbifom_container_t *source = (ogs_nas_nbifom_container_t *)pkbuf->data;
+ ogs_nas_nbifom_container_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_nbifom_container_t *)pkbuf->data;
nbifom_container->length = source->length;
size = nbifom_container->length + sizeof(nbifom_container->length);
@@ -3702,7 +4080,14 @@ int ogs_nas_eps_encode_nbifom_container(ogs_pkbuf_t *pkbuf, ogs_nas_nbifom_conta
int ogs_nas_eps_decode_apn_aggregate_maximum_bit_rate(ogs_nas_apn_aggregate_maximum_bit_rate_t *apn_aggregate_maximum_bit_rate, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_apn_aggregate_maximum_bit_rate_t *source = (ogs_nas_apn_aggregate_maximum_bit_rate_t *)pkbuf->data;
+ ogs_nas_apn_aggregate_maximum_bit_rate_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_apn_aggregate_maximum_bit_rate_t *)pkbuf->data;
apn_aggregate_maximum_bit_rate->length = source->length;
size = apn_aggregate_maximum_bit_rate->length + sizeof(apn_aggregate_maximum_bit_rate->length);
@@ -3741,7 +4126,14 @@ int ogs_nas_eps_encode_apn_aggregate_maximum_bit_rate(ogs_pkbuf_t *pkbuf, ogs_na
int ogs_nas_eps_decode_header_compression_configuration(ogs_nas_header_compression_configuration_t *header_compression_configuration, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_header_compression_configuration_t *source = (ogs_nas_header_compression_configuration_t *)pkbuf->data;
+ ogs_nas_header_compression_configuration_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_header_compression_configuration_t *)pkbuf->data;
header_compression_configuration->length = source->length;
size = header_compression_configuration->length + sizeof(header_compression_configuration->length);
@@ -3816,7 +4208,14 @@ int ogs_nas_eps_encode_control_plane_only_indication(ogs_pkbuf_t *pkbuf, ogs_nas
int ogs_nas_eps_decode_extended_protocol_configuration_options(ogs_nas_extended_protocol_configuration_options_t *extended_protocol_configuration_options, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_protocol_configuration_options_t *source = (ogs_nas_extended_protocol_configuration_options_t *)pkbuf->data;
+ ogs_nas_extended_protocol_configuration_options_t *source = NULL;
+
+ if (pkbuf->len < 2) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_protocol_configuration_options_t *)pkbuf->data;
extended_protocol_configuration_options->length = be16toh(source->length);
size = extended_protocol_configuration_options->length + sizeof(extended_protocol_configuration_options->length);
@@ -3862,7 +4261,14 @@ int ogs_nas_eps_encode_extended_protocol_configuration_options(ogs_pkbuf_t *pkbu
int ogs_nas_eps_decode_header_compression_configuration_status(ogs_nas_header_compression_configuration_status_t *header_compression_configuration_status, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_header_compression_configuration_status_t *source = (ogs_nas_header_compression_configuration_status_t *)pkbuf->data;
+ ogs_nas_header_compression_configuration_status_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_header_compression_configuration_status_t *)pkbuf->data;
header_compression_configuration_status->length = source->length;
size = header_compression_configuration_status->length + sizeof(header_compression_configuration_status->length);
@@ -3901,7 +4307,14 @@ int ogs_nas_eps_encode_header_compression_configuration_status(ogs_pkbuf_t *pkbu
int ogs_nas_eps_decode_serving_plmn_rate_control(ogs_nas_serving_plmn_rate_control_t *serving_plmn_rate_control, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_serving_plmn_rate_control_t *source = (ogs_nas_serving_plmn_rate_control_t *)pkbuf->data;
+ ogs_nas_serving_plmn_rate_control_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_serving_plmn_rate_control_t *)pkbuf->data;
serving_plmn_rate_control->length = source->length;
size = serving_plmn_rate_control->length + sizeof(serving_plmn_rate_control->length);
@@ -3940,7 +4353,14 @@ int ogs_nas_eps_encode_serving_plmn_rate_control(ogs_pkbuf_t *pkbuf, ogs_nas_ser
int ogs_nas_eps_decode_extended_apn_aggregate_maximum_bit_rate(ogs_nas_extended_apn_aggregate_maximum_bit_rate_t *extended_apn_aggregate_maximum_bit_rate, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_apn_aggregate_maximum_bit_rate_t *source = (ogs_nas_extended_apn_aggregate_maximum_bit_rate_t *)pkbuf->data;
+ ogs_nas_extended_apn_aggregate_maximum_bit_rate_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_apn_aggregate_maximum_bit_rate_t *)pkbuf->data;
extended_apn_aggregate_maximum_bit_rate->length = source->length;
size = extended_apn_aggregate_maximum_bit_rate->length + sizeof(extended_apn_aggregate_maximum_bit_rate->length);
@@ -4011,7 +4431,14 @@ int ogs_nas_eps_encode_connectivity_type(ogs_pkbuf_t *pkbuf, ogs_nas_connectivit
int ogs_nas_eps_decode_eps_quality_of_service(ogs_nas_eps_quality_of_service_t *eps_quality_of_service, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_eps_quality_of_service_t *source = (ogs_nas_eps_quality_of_service_t *)pkbuf->data;
+ ogs_nas_eps_quality_of_service_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_eps_quality_of_service_t *)pkbuf->data;
eps_quality_of_service->length = source->length;
size = eps_quality_of_service->length + sizeof(eps_quality_of_service->length);
@@ -4050,7 +4477,14 @@ int ogs_nas_eps_encode_eps_quality_of_service(ogs_pkbuf_t *pkbuf, ogs_nas_eps_qu
int ogs_nas_eps_decode_extended_quality_of_service(ogs_nas_extended_quality_of_service_t *extended_quality_of_service, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_extended_quality_of_service_t *source = (ogs_nas_extended_quality_of_service_t *)pkbuf->data;
+ ogs_nas_extended_quality_of_service_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_extended_quality_of_service_t *)pkbuf->data;
extended_quality_of_service->length = source->length;
size = extended_quality_of_service->length + sizeof(extended_quality_of_service->length);
@@ -4223,7 +4657,14 @@ int ogs_nas_eps_encode_llc_service_access_point_identifier(ogs_pkbuf_t *pkbuf, o
int ogs_nas_eps_decode_packet_flow_identifier(ogs_nas_packet_flow_identifier_t *packet_flow_identifier, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_packet_flow_identifier_t *source = (ogs_nas_packet_flow_identifier_t *)pkbuf->data;
+ ogs_nas_packet_flow_identifier_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_packet_flow_identifier_t *)pkbuf->data;
packet_flow_identifier->length = source->length;
size = packet_flow_identifier->length + sizeof(packet_flow_identifier->length);
@@ -4262,7 +4703,14 @@ int ogs_nas_eps_encode_packet_flow_identifier(ogs_pkbuf_t *pkbuf, ogs_nas_packet
int ogs_nas_eps_decode_pdn_address(ogs_nas_pdn_address_t *pdn_address, ogs_pkbuf_t *pkbuf)
{
int size = 0;
- ogs_nas_pdn_address_t *source = (ogs_nas_pdn_address_t *)pkbuf->data;
+ ogs_nas_pdn_address_t *source = NULL;
+
+ if (pkbuf->len < 1) {
+ ogs_error("Not enough pkbuf [len:%d]", pkbuf->len);
+ return -1;
+ }
+
+ source = (ogs_nas_pdn_address_t *)pkbuf->data;
pdn_address->length = source->length;
size = pdn_address->length + sizeof(pdn_address->length);
diff --git a/lib/nas/eps/support/nas-message.py b/lib/nas/eps/support/nas-message.py
index 19b1354bb..e882cf60a 100644
--- a/lib/nas/eps/support/nas-message.py
+++ b/lib/nas/eps/support/nas-message.py
@@ -461,7 +461,12 @@ for (k, v) in sorted_type_list:
f.write("int ogs_nas_eps_decode_%s(ogs_nas_%s_t *%s, ogs_pkbuf_t *pkbuf)\n" % (v_lower(k), v_lower(k), v_lower(k)))
f.write("{\n")
f.write(" int size = 0;\n")
- f.write(" ogs_nas_%s_t *source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % (v_lower(k), v_lower(k)))
+ f.write(" ogs_nas_%s_t *source = NULL;\n\n" % v_lower(k))
+ f.write(" if (pkbuf->len < 2) {\n")
+ f.write(" ogs_error(\"Not enough pkbuf [len:%d]\", pkbuf->len);\n")
+ f.write(" return -1;\n")
+ f.write(" }\n\n")
+ f.write(" source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % v_lower(k))
f.write(" %s->length = be16toh(source->length);\n" % v_lower(k))
f.write(" size = %s->length + sizeof(%s->length);\n\n" % (v_lower(k), v_lower(k)))
f.write(" if (ogs_pkbuf_pull(pkbuf, size) == NULL) {\n")
@@ -494,7 +499,12 @@ for (k, v) in sorted_type_list:
f.write("int ogs_nas_eps_decode_%s(ogs_nas_%s_t *%s, ogs_pkbuf_t *pkbuf)\n" % (v_lower(k), v_lower(k), v_lower(k)))
f.write("{\n")
f.write(" int size = 0;\n")
- f.write(" ogs_nas_%s_t *source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % (v_lower(k), v_lower(k)))
+ f.write(" ogs_nas_%s_t *source = NULL;\n\n" % v_lower(k))
+ f.write(" if (pkbuf->len < 1) {\n")
+ f.write(" ogs_error(\"Not enough pkbuf [len:%d]\", pkbuf->len);\n")
+ f.write(" return -1;\n")
+ f.write(" }\n\n")
+ f.write(" source = (ogs_nas_%s_t *)pkbuf->data;\n\n" % v_lower(k))
f.write(" %s->length = source->length;\n" % v_lower(k))
f.write(" size = %s->length + sizeof(%s->length);\n\n" % (v_lower(k), v_lower(k)))
f.write(" if (ogs_pkbuf_pull(pkbuf, size) == NULL) {\n")
diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c
index a87661635..74ecf0b07 100644
--- a/lib/pfcp/context.c
+++ b/lib/pfcp/context.c
@@ -26,7 +26,6 @@ static int context_initialized = 0;
static OGS_POOL(ogs_pfcp_node_pool, ogs_pfcp_node_t);
-static OGS_POOL(ogs_pfcp_sess_pool, ogs_pfcp_sess_t);
static OGS_POOL(ogs_pfcp_far_pool, ogs_pfcp_far_t);
static OGS_POOL(ogs_pfcp_urr_pool, ogs_pfcp_urr_t);
static OGS_POOL(ogs_pfcp_qer_pool, ogs_pfcp_qer_t);
@@ -55,8 +54,6 @@ void ogs_pfcp_context_init(void)
ogs_pool_init(&ogs_pfcp_node_pool, ogs_app()->pool.nf);
- ogs_pool_init(&ogs_pfcp_sess_pool, ogs_app()->pool.sess);
-
ogs_pool_init(&ogs_pfcp_far_pool,
ogs_app()->pool.sess * OGS_MAX_NUM_OF_FAR);
ogs_pool_init(&ogs_pfcp_urr_pool,
@@ -116,7 +113,6 @@ void ogs_pfcp_context_final(void)
ogs_pool_final(&ogs_pfcp_pdr_teid_pool);
ogs_free(pdr_random_to_index);
- ogs_pool_final(&ogs_pfcp_sess_pool);
ogs_pool_final(&ogs_pfcp_far_pool);
ogs_pool_final(&ogs_pfcp_urr_pool);
ogs_pool_final(&ogs_pfcp_qer_pool);
@@ -371,6 +367,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
server_key);
}
+ /* Add address information */
addr = NULL;
for (i = 0; i < num; i++) {
rv = ogs_addaddrinfo(&addr,
@@ -378,20 +375,34 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
ogs_assert(rv == OGS_OK);
}
+ /* Add each address as a separate socknode */
if (addr) {
- if (ogs_global_conf()->
- parameter.no_ipv4 == 0)
- ogs_socknode_add(
- &self.pfcp_list, AF_INET, addr,
- is_option ? &option : NULL);
- if (ogs_global_conf()->
- parameter.no_ipv6 == 0)
- ogs_socknode_add(
- &self.pfcp_list6, AF_INET6, addr,
- is_option ? &option : NULL);
+ ogs_sockaddr_t *current = addr;
+ while (current) {
+ if (current->ogs_sa_family ==
+ AF_INET &&
+ ogs_global_conf()->
+ parameter.no_ipv4 == 0) {
+ ogs_socknode_add(&self.pfcp_list,
+ AF_INET, current,
+ is_option ?
+ &option : NULL);
+ }
+ if (current->ogs_sa_family ==
+ AF_INET6 &&
+ ogs_global_conf()->
+ parameter.no_ipv6 == 0) {
+ ogs_socknode_add(&self.pfcp_list6,
+ AF_INET6, current,
+ is_option ?
+ &option : NULL);
+ }
+ current = current->next;
+ }
ogs_freeaddrinfo(addr);
}
+ /* Process advertise addresses if needed */
addr = NULL;
for (i = 0; i < num_of_advertise; i++) {
rv = ogs_addaddrinfo(&addr,
@@ -420,6 +431,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
ogs_freeaddrinfo(addr);
}
+ /* Bind to device if specified */
if (dev) {
rv = ogs_socknode_probe(
ogs_global_conf()->
@@ -852,20 +864,43 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
return OGS_OK;
}
-ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *sa_list)
+/******************************************************************************
+ * ogs_pfcp_node_new()
+ * - Initialize node_id.type to OGS_PFCP_NODE_ID_UNKNOWN
+ * - So the node can later be updated with a real Node ID via
+ * ogs_pfcp_node_merge() once we learn it from PFCP messages.
+ ******************************************************************************/
+ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *config_addr)
{
+ int rv;
ogs_pfcp_node_t *node = NULL;
- ogs_assert(sa_list);
-
ogs_pool_alloc(&ogs_pfcp_node_pool, &node);
if (!node) {
- ogs_error("No memory: ogs_pool_alloc() failed");
+ ogs_error("No memory: ogs_pool_alloc() failed [%s]",
+ ogs_sockaddr_to_string_static(config_addr));
return NULL;
}
memset(node, 0, sizeof(ogs_pfcp_node_t));
- node->sa_list = sa_list;
+ /* Store config_addr, if any */
+ node->config_addr = config_addr;
+
+ /* If config_addr is given, copy it immediately into addr_list */
+ if (config_addr) {
+ rv = ogs_copyaddrinfo(&node->addr_list, config_addr);
+ if (rv != OGS_OK) {
+ ogs_error("ogs_copyaddrinfo() failed");
+ ogs_pool_free(&ogs_pfcp_node_pool, node);
+ return NULL;
+ }
+ }
+
+ /*
+ * Initialize node->node_id to UNKNOWN, meaning "no Node ID assigned yet".
+ */
+ memset(&node->node_id, 0, sizeof(node->node_id));
+ node->node_id.type = OGS_PFCP_NODE_ID_UNKNOWN;
ogs_list_init(&node->local_list);
ogs_list_init(&node->remote_list);
@@ -883,49 +918,199 @@ void ogs_pfcp_node_free(ogs_pfcp_node_t *node)
ogs_pfcp_xact_delete_all(node);
- ogs_freeaddrinfo(node->sa_list);
+ ogs_freeaddrinfo(node->config_addr);
+ ogs_freeaddrinfo(node->addr_list);
+
ogs_pool_free(&ogs_pfcp_node_pool, node);
}
-ogs_pfcp_node_t *ogs_pfcp_node_add(
- ogs_list_t *list, ogs_sockaddr_t *addr)
+/******************************************************************************
+ * ogs_pfcp_node_add()
+ * - Create a new PFCP node, then call ogs_pfcp_node_merge() to handle
+ * IPv4/IPv6 or FQDN logic.
+ ******************************************************************************/
+ogs_pfcp_node_t *ogs_pfcp_node_add(ogs_list_t *list,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from)
{
ogs_pfcp_node_t *node = NULL;
- ogs_sockaddr_t *new = NULL;
ogs_assert(list);
- ogs_assert(addr);
+ ogs_assert(node_id && from);
- ogs_assert(OGS_OK == ogs_copyaddrinfo(&new, addr));
- node = ogs_pfcp_node_new(new);
- if (!node) {
- ogs_error("No memory : ogs_pfcp_node_new() failed");
- ogs_freeaddrinfo(new);
+ /*
+ * We only handle IPv4, IPv6, and FQDN types here. If the incoming
+ * node_id has any other type, we treat it as invalid. This ensures
+ * we do not merge a node with an unsupported PFCP Node ID.
+ */
+ if (node_id->type != OGS_PFCP_NODE_ID_IPV4 &&
+ node_id->type != OGS_PFCP_NODE_ID_IPV6 &&
+ node_id->type != OGS_PFCP_NODE_ID_FQDN) {
+ ogs_error("Invalid PFCP Node Type = %d", node_id->type);
return NULL;
}
- ogs_assert(node);
- memcpy(&node->addr, new, sizeof node->addr);
+ /* Create node with no config_addr initially */
+ node = ogs_pfcp_node_new(NULL);
+ if (!node) {
+ ogs_error("No memory: ogs_pfcp_node_add() failed node_id:%s from:%s",
+ ogs_pfcp_node_id_to_string_static(node_id),
+ ogs_sockaddr_to_string_static(from));
+ return NULL;
+ }
+
+ /* Set node->node_id, reset last_dns_refresh. */
+ memcpy(&node->node_id, node_id, sizeof(node->node_id));
+ node->last_dns_refresh = 0;
+
+ /* Merge addresses => fill node->addr_list if conditions are met */
+ if (ogs_pfcp_node_merge(node, node_id, from) != OGS_OK) {
+ ogs_error("ogs_pfcp_node_merge() failed node_id [%s] from [%s]",
+ ogs_pfcp_node_id_to_string_static(node_id),
+ ogs_sockaddr_to_string_static(from));
+ ogs_pool_free(&ogs_pfcp_node_pool, node);
+ return NULL;
+ }
ogs_list_add(list, node);
return node;
}
-ogs_pfcp_node_t *ogs_pfcp_node_find(
- ogs_list_t *list, ogs_sockaddr_t *addr)
+/******************************************************************************
+ * ogs_pfcp_node_find()
+ * - No DNS logic here. Merely finds a node by node_id (if provided) and
+ * checks if 'from' address is in node->addr_list.
+ ******************************************************************************/
+ogs_pfcp_node_t *ogs_pfcp_node_find(ogs_list_t *list,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from)
{
- ogs_pfcp_node_t *node = NULL;
+ ogs_pfcp_node_t *cur;
ogs_assert(list);
- ogs_assert(addr);
+ ogs_assert(node_id || from);
- ogs_list_for_each(list, node) {
- if (ogs_sockaddr_is_equal(&node->addr, addr) == true)
- break;
+ ogs_list_for_each(list, cur) {
+ /*
+ * If the node currently has a known Node ID (not UNKNOWN)
+ * and the caller provided a node_id to match, then compare them.
+ * If they do not match, skip this node. This allows config-based nodes
+ * (with an UNKNOWN node_id) to be found by IP address alone,
+ * while nodes with a definite ID must match the incoming node_id.
+ */
+ if (cur->node_id.type != OGS_PFCP_NODE_ID_UNKNOWN && node_id) {
+ if (!ogs_pfcp_node_id_compare(&cur->node_id, node_id))
+ continue;
+ }
+ if (!from)
+ return cur;
+
+ /* Check if 'from' is in cur->addr_list. */
+ if (ogs_sockaddr_check_any_match(cur->addr_list, NULL,
+ from, /* compare_port= */ true)) {
+ return cur;
+ }
}
- return node;
+ /* No match found. */
+ return NULL;
+}
+
+/******************************************************************************
+ * ogs_pfcp_node_merge():
+ * - If node_id changes to FQDN, we check last_dns_refresh.
+ * => If 0, do an immediate DNS resolution (first time).
+ * => If >= 300 seconds passed, do a periodic refresh.
+ * => Otherwise, skip.
+ * - If node_id changes to IPv4/IPv6, convert IP addresses immediately.
+ * - Merge the 'from' address into addr_list if provided.
+ ******************************************************************************/
+int ogs_pfcp_node_merge(ogs_pfcp_node_t *node,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from)
+{
+ ogs_sockaddr_t single;
+ ogs_sockaddr_t *tmp_list = NULL;
+
+ ogs_assert(node);
+ ogs_assert(node_id || from);
+
+ if (node_id) {
+ /*
+ * We only handle IPv4, IPv6, and FQDN types here. If the incoming
+ * node_id has any other type, we treat it as invalid. This ensures
+ * we do not merge a node with an unsupported PFCP Node ID.
+ */
+ if (node_id->type != OGS_PFCP_NODE_ID_IPV4 &&
+ node_id->type != OGS_PFCP_NODE_ID_IPV6 &&
+ node_id->type != OGS_PFCP_NODE_ID_FQDN) {
+ ogs_error("Invalid PFCP Node Type = %d", node_id->type);
+ return OGS_ERROR;
+ }
+
+ /* Check if node_id is different from node->node_id. */
+ if (!ogs_pfcp_node_id_compare(&node->node_id, node_id)) {
+ /* Update the node's ID and reset the refresh timestamp. */
+ memcpy(&node->node_id, node_id, sizeof(node->node_id));
+ node->last_dns_refresh = 0;
+ }
+
+ /* If FQDN, do a DNS lookup (immediate or periodic). */
+ if (node->node_id.type == OGS_PFCP_NODE_ID_FQDN) {
+/*
+ * We perform a DNS resolution if 'last_dns_refresh' is zero, which means
+ * this FQDN node has never been resolved yet (first-time resolution), or if
+ * at least 300 seconds have passed since the last refresh. Without checking
+ * '== 0', a newly created FQDN node might skip resolution if 'now' is less
+ * than the 300-second threshold.
+ */
+ ogs_time_t now = ogs_time_now();
+
+/* For 300-second refresh interval in microseconds. */
+#define OGS_PFCP_NODE_DNS_REFRESH_INTERVAL \
+ ((ogs_time_t)(300) * OGS_USEC_PER_SEC)
+ if (node->last_dns_refresh == 0 ||
+ (now - node->last_dns_refresh) >=
+ OGS_PFCP_NODE_DNS_REFRESH_INTERVAL) {
+
+ tmp_list = ogs_pfcp_node_id_to_addrinfo(&node->node_id);
+ if (!tmp_list) {
+ ogs_error("DNS resolution failed for FQDN [%s]",
+ node->node_id.fqdn);
+ return OGS_ERROR;
+ }
+
+ ogs_freeaddrinfo(node->addr_list);
+ node->addr_list = tmp_list;
+ node->last_dns_refresh = now;
+ tmp_list = NULL;
+ }
+ }
+ /* If IPv4/IPv6, convert immediately. */
+ else if (node->node_id.type == OGS_PFCP_NODE_ID_IPV4 ||
+ node->node_id.type == OGS_PFCP_NODE_ID_IPV6) {
+ tmp_list = ogs_pfcp_node_id_to_addrinfo(&node->node_id);
+ if (!tmp_list) {
+ ogs_error("Failed to convert node ID to address info");
+ return OGS_ERROR;
+ }
+ ogs_merge_addrinfo(&node->addr_list, tmp_list);
+ ogs_freeaddrinfo(tmp_list);
+ tmp_list = NULL;
+ }
+ else {
+ /* Not IPv4, IPv6, or FQDN => invalid node type. */
+ ogs_error("Invalid Node ID type [%d]", node->node_id.type);
+ return OGS_ERROR;
+ }
+ }
+
+ /* Merge 'from' into addr_list if provided. */
+ if (from) {
+ memcpy(&single, from, sizeof(single));
+ single.next = NULL;
+ ogs_merge_addrinfo(&node->addr_list, &single);
+ }
+
+ return OGS_OK;
}
void ogs_pfcp_node_remove(ogs_list_t *list, ogs_pfcp_node_t *node)
@@ -947,6 +1132,37 @@ void ogs_pfcp_node_remove_all(ogs_list_t *list)
ogs_pfcp_node_remove(list, node);
}
+/******************************************************************************
+ * Compare two node IDs for equality. Returns true if they match, else false.
+ ******************************************************************************/
+bool ogs_pfcp_node_id_compare(
+ const ogs_pfcp_node_id_t *id1, const ogs_pfcp_node_id_t *id2)
+{
+ if (id1->type != id2->type)
+ return false; /* Types do not match */
+
+ switch (id1->type) {
+ case OGS_PFCP_NODE_ID_IPV4:
+ if (id1->addr != id2->addr) return false;
+ return true;
+
+ case OGS_PFCP_NODE_ID_IPV6:
+ if (memcmp(id1->addr6, id2->addr6, OGS_IPV6_LEN) != 0)
+ return false;
+ return true;
+
+ case OGS_PFCP_NODE_ID_FQDN:
+ if (strcmp(id1->fqdn, id2->fqdn) != 0)
+ return false;
+ return true;
+
+ default:
+ ogs_error("Unexpected Node Type [%d]", id1->type);
+ ogs_abort();
+ return false; /* Unknown types do not match */
+ }
+}
+
ogs_gtpu_resource_t *ogs_pfcp_find_gtpu_resource(ogs_list_t *list,
char *dnn, ogs_pfcp_interface_t source_interface)
{
@@ -1144,6 +1360,7 @@ void ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr)
int i = 0;
ogs_assert(pdr);
+ ogs_assert(!pdr->f_teid.ch);
ogs_assert(pdr->f_teid.teid > 0 &&
pdr->f_teid.teid <= ogs_pfcp_pdr_teid_pool.size);
@@ -1871,10 +2088,10 @@ void ogs_pfcp_bar_delete(ogs_pfcp_bar_t *bar)
if (bar->id_node)
ogs_pool_free(&bar->sess->bar_id_pool, bar->id_node);
- ogs_pool_free(&ogs_pfcp_bar_pool, bar);
-
bar->sess = NULL;
sess->bar = NULL;
+
+ ogs_pool_free(&ogs_pfcp_bar_pool, bar);
}
ogs_pfcp_rule_t *ogs_pfcp_rule_add(ogs_pfcp_pdr_t *pdr)
diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h
index 609d74ed8..70b253be3 100644
--- a/lib/pfcp/context.h
+++ b/lib/pfcp/context.h
@@ -84,10 +84,20 @@ typedef struct ogs_pfcp_context_s {
typedef struct ogs_pfcp_node_s {
ogs_lnode_t lnode; /* A node of list_t */
- ogs_sockaddr_t *sa_list; /* Socket Address List Candidate */
+ ogs_sockaddr_t *config_addr; /* Configured addresses */
+ ogs_pfcp_node_id_t node_id; /* PFCP node ID */
- ogs_sock_t *sock; /* Socket Instance */
- ogs_sockaddr_t addr; /* Remote Address */
+ /* List of addresses:: final merged address list */
+ ogs_sockaddr_t *addr_list;
+
+ /*
+ * Iterator for round-robin sendto operations.
+ * Points to the current address in the round-robin sequence.
+ */
+ ogs_sockaddr_t *current_addr;
+
+ /* Timestamp of last DNS refresh for FQDN nodes. */
+ ogs_time_t last_dns_refresh;
ogs_list_t local_list;
ogs_list_t remote_list;
@@ -399,15 +409,19 @@ void ogs_pfcp_context_final(void);
ogs_pfcp_context_t *ogs_pfcp_self(void);
int ogs_pfcp_context_parse_config(const char *local, const char *remote);
-ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *sa_list);
+ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *config_addr);
void ogs_pfcp_node_free(ogs_pfcp_node_t *node);
-ogs_pfcp_node_t *ogs_pfcp_node_add(
- ogs_list_t *list, ogs_sockaddr_t *addr);
-ogs_pfcp_node_t *ogs_pfcp_node_find(
- ogs_list_t *list, ogs_sockaddr_t *addr);
+ogs_pfcp_node_t *ogs_pfcp_node_add(ogs_list_t *list,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from);
+ogs_pfcp_node_t *ogs_pfcp_node_find(ogs_list_t *list,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from);
+int ogs_pfcp_node_merge(ogs_pfcp_node_t *node,
+ ogs_pfcp_node_id_t *node_id, ogs_sockaddr_t *from);
void ogs_pfcp_node_remove(ogs_list_t *list, ogs_pfcp_node_t *node);
void ogs_pfcp_node_remove_all(ogs_list_t *list);
+bool ogs_pfcp_node_id_compare(
+ const ogs_pfcp_node_id_t *id1, const ogs_pfcp_node_id_t *id2);
ogs_gtpu_resource_t *ogs_pfcp_find_gtpu_resource(ogs_list_t *list,
char *dnn, ogs_pfcp_interface_t source_interface);
diff --git a/lib/pfcp/handler.c b/lib/pfcp/handler.c
index 0ab5cfeb0..a8e24ce6a 100644
--- a/lib/pfcp/handler.c
+++ b/lib/pfcp/handler.c
@@ -130,14 +130,9 @@ bool ogs_pfcp_cp_handle_association_setup_request(
}
}
- if (node->up_function_features.ftup == 0) {
- char buf[OGS_ADDRSTRLEN];
- ogs_sockaddr_t *addr = node->sa_list;
- ogs_assert(addr);
-
- ogs_warn("F-TEID allocation/release not supported with peer [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
- }
+ if (node->up_function_features.ftup == 0)
+ ogs_warn("F-TEID allocation/release not supported with peer %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
return true;
}
@@ -182,14 +177,9 @@ bool ogs_pfcp_cp_handle_association_setup_response(
}
}
- if (node->up_function_features.ftup == 0) {
- char buf[OGS_ADDRSTRLEN];
- ogs_sockaddr_t *addr = node->sa_list;
- ogs_assert(addr);
-
- ogs_warn("F-TEID allocation/release not supported with peer [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
- }
+ if (node->up_function_features.ftup == 0)
+ ogs_warn("F-TEID allocation/release not supported with peer %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
return true;
}
diff --git a/lib/pfcp/meson.build b/lib/pfcp/meson.build
index 910b50828..50b524852 100644
--- a/lib/pfcp/meson.build
+++ b/lib/pfcp/meson.build
@@ -45,6 +45,7 @@ libpfcp_sources = files('''
xact.h
context.h
rule-match.h
+ util.h
message.c
types.c
@@ -55,6 +56,7 @@ libpfcp_sources = files('''
xact.c
context.c
rule-match.c
+ util.c
'''.split())
libpfcp_inc = include_directories('.')
diff --git a/lib/pfcp/ogs-pfcp.h b/lib/pfcp/ogs-pfcp.h
index 7403ba80d..e6ea050a3 100644
--- a/lib/pfcp/ogs-pfcp.h
+++ b/lib/pfcp/ogs-pfcp.h
@@ -43,6 +43,7 @@
#include "pfcp/path.h"
#include "pfcp/xact.h"
#include "pfcp/handler.h"
+#include "pfcp/util.h"
#ifdef __cplusplus
extern "C" {
diff --git a/lib/pfcp/path.c b/lib/pfcp/path.c
index 203c4d5e7..14c9a6986 100644
--- a/lib/pfcp/path.c
+++ b/lib/pfcp/path.c
@@ -36,69 +36,6 @@ ogs_sock_t *ogs_pfcp_server(ogs_socknode_t *node)
return pfcp;
}
-int ogs_pfcp_connect(
- ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *node)
-{
- ogs_sockaddr_t *addr;
- char buf[OGS_ADDRSTRLEN];
-
- ogs_assert(ipv4 || ipv6);
- ogs_assert(node);
- ogs_assert(node->sa_list);
-
- addr = node->sa_list;
- while (addr) {
- ogs_sock_t *sock = NULL;
-
- if (addr->ogs_sa_family == AF_INET)
- sock = ipv4;
- else if (addr->ogs_sa_family == AF_INET6)
- sock = ipv6;
- else
- ogs_assert_if_reached();
-
- if (sock) {
- ogs_info("ogs_pfcp_connect() [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
-
- node->sock = sock;
- memcpy(&node->addr, addr, sizeof node->addr);
- break;
- }
-
- addr = addr->next;
- }
-
- if (addr == NULL) {
- ogs_error("ogs_pfcp_connect() [%s]:%d failed",
- OGS_ADDR(node->sa_list, buf), OGS_PORT(node->sa_list));
- ogs_error("Please check the IP version between SMF and UPF nodes.");
- return OGS_ERROR;
- }
-
- return OGS_OK;
-}
-
-int ogs_pfcp_send(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
-{
- ssize_t sent;
- ogs_sock_t *sock = NULL;
-
- ogs_assert(node);
- ogs_assert(pkbuf);
- sock = node->sock;
- ogs_assert(sock);
-
- sent = ogs_send(sock->fd, pkbuf->data, pkbuf->len, 0);
- if (sent < 0 || sent != pkbuf->len) {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "ogs_pfcp_send() failed");
- return OGS_ERROR;
- }
-
- return OGS_OK;
-}
-
int ogs_pfcp_sendto(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
{
ssize_t sent;
@@ -107,11 +44,34 @@ int ogs_pfcp_sendto(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
ogs_assert(node);
ogs_assert(pkbuf);
- sock = node->sock;
- ogs_assert(sock);
- addr = &node->addr;
+ ogs_assert(node->addr_list);
+
+ /* Initialize round-robin iterator if needed */
+ if (node->current_addr == NULL) {
+ node->current_addr = node->addr_list;
+ }
+ addr = node->current_addr;
ogs_assert(addr);
+ if (addr->ogs_sa_family == AF_INET) {
+ sock = ogs_pfcp_self()->pfcp_sock;
+ if (!sock) {
+ ogs_error("IPv4 socket (pfcp_sock) is not available. "
+ "Ensure that 'pfcp.server.address: 127.0.0.1' "
+ "is set in the YAML configuration file.");
+ return OGS_ERROR;
+ }
+ } else if (addr->ogs_sa_family == AF_INET6) {
+ sock = ogs_pfcp_self()->pfcp_sock6;
+ if (!sock) {
+ ogs_error("IPv6 socket (pfcp_sock) is not available. "
+ "Ensure that 'pfcp.server.address: [::1]' "
+ "is set in the YAML configuration file.");
+ return OGS_ERROR;
+ }
+ } else
+ ogs_assert_if_reached();
+
sent = ogs_sendto(sock->fd, pkbuf->data, pkbuf->len, 0, addr);
if (sent < 0 || sent != pkbuf->len) {
if (ogs_socket_errno != OGS_EAGAIN) {
@@ -125,6 +85,13 @@ int ogs_pfcp_sendto(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf)
return OGS_ERROR;
}
+ /* Move to next address in round-robin sequence */
+ if (node->current_addr->next)
+ node->current_addr = node->current_addr->next;
+ else
+ /* If end of list reached, wrap around to the start */
+ node->current_addr = node->addr_list;
+
return OGS_OK;
}
diff --git a/lib/pfcp/path.h b/lib/pfcp/path.h
index d7f6c3278..eae2605fd 100644
--- a/lib/pfcp/path.h
+++ b/lib/pfcp/path.h
@@ -56,10 +56,6 @@ extern "C" {
typedef struct ogs_pfcp_xact_s ogs_pfcp_xact_t;
ogs_sock_t *ogs_pfcp_server(ogs_socknode_t *node);
-int ogs_pfcp_connect(
- ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_pfcp_node_t *node);
-
-int ogs_pfcp_send(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf);
int ogs_pfcp_sendto(ogs_pfcp_node_t *node, ogs_pkbuf_t *pkbuf);
ogs_pkbuf_t *ogs_pfcp_handle_echo_req(ogs_pkbuf_t *pkt);
diff --git a/lib/pfcp/types.h b/lib/pfcp/types.h
index 433382f5d..cbe9df7de 100644
--- a/lib/pfcp/types.h
+++ b/lib/pfcp/types.h
@@ -550,9 +550,17 @@ typedef struct ogs_pfcp_outer_header_removal_s {
uint8_t gtpu_extheader_deletion;
} ogs_pfcp_outer_header_removal_t;
+/******************************************************************************
+ * PFCP Node ID structure
+ ******************************************************************************/
#define OGS_PFCP_NODE_ID_IPV4 0
#define OGS_PFCP_NODE_ID_IPV6 1
#define OGS_PFCP_NODE_ID_FQDN 2
+
+/******************************************************************************
+ * Add this line to define the UNKNOWN type. We use '3' since 0,1,2 are taken.
+ ******************************************************************************/
+#define OGS_PFCP_NODE_ID_UNKNOWN 0xf
typedef struct ogs_pfcp_node_id_s {
ED2(uint8_t spare:4;,
uint8_t type:4;)
diff --git a/lib/pfcp/util.c b/lib/pfcp/util.c
new file mode 100644
index 000000000..295f1211c
--- /dev/null
+++ b/lib/pfcp/util.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2025 by Sukchan Lee
+ *
+ * This file is part of Open5GS.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "ogs-pfcp.h"
+
+/*
+ * Requirements of Node ID:
+ * NONE : Node ID must not be present
+ * OPTIONAL : Node ID may or may not be present
+ * MANDATORY : Node ID must be present
+ */
+#define OGS_PFCP_NODE_ID_NONE 0
+#define OGS_PFCP_NODE_ID_OPTIONAL 1
+#define OGS_PFCP_NODE_ID_MANDATORY 2
+
+/*
+ * This function extracts the PFCP Node ID from the given PFCP message.
+ * It determines the Node ID field location and requirement based on
+ * the message type. Then it validates presence and copies data into
+ * 'node_id'. If Node ID is not consistent with the requirement, an
+ * error status is returned.
+ */
+ogs_pfcp_status_e
+ogs_pfcp_extract_node_id(ogs_pfcp_message_t *message,
+ ogs_pfcp_node_id_t *node_id)
+{
+
+ /* For C89 compliance, all variables are declared upfront. */
+ ogs_pfcp_tlv_node_id_t *tlv_node_id = NULL;
+ int requirement = OGS_PFCP_NODE_ID_NONE;
+ ogs_pfcp_status_e status = OGS_PFCP_STATUS_SUCCESS;
+
+ /* Validate input pointers */
+ ogs_assert(message);
+ ogs_assert(node_id);
+
+ /* Initialize the output structure */
+ memset(node_id, 0, sizeof(*node_id));
+
+ /* Determine the location of node_id TLV and requirement */
+ switch (message->h.type) {
+ case OGS_PFCP_PFD_MANAGEMENT_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_pfd_management_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_OPTIONAL;
+ break;
+
+ case OGS_PFCP_PFD_MANAGEMENT_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_pfd_management_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_OPTIONAL;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_association_setup_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_association_setup_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_UPDATE_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_association_update_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_UPDATE_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_association_update_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_RELEASE_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_association_release_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_ASSOCIATION_RELEASE_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_association_release_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_NODE_REPORT_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_node_report_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_NODE_REPORT_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_node_report_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_SET_DELETION_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_session_set_deletion_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_session_set_deletion_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_SET_MODIFICATION_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_session_set_modification_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_SET_MODIFICATION_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_session_set_modification_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_session_establishment_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE:
+ tlv_node_id = &message->pfcp_session_establishment_response.node_id;
+ requirement = OGS_PFCP_NODE_ID_MANDATORY;
+ break;
+
+ case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
+ tlv_node_id = &message->pfcp_session_modification_request.node_id;
+ requirement = OGS_PFCP_NODE_ID_OPTIONAL;
+ break;
+
+ /* Add other message types with node_id here as needed */
+
+ case OGS_PFCP_HEARTBEAT_REQUEST_TYPE:
+ case OGS_PFCP_HEARTBEAT_RESPONSE_TYPE:
+ case OGS_PFCP_VERSION_NOT_SUPPORTED_RESPONSE_TYPE:
+ case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE:
+ case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
+ case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
+ case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:
+ case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE:
+ /* Node ID must not be present for these messages */
+ requirement = OGS_PFCP_NODE_ID_NONE;
+ break;
+
+ default:
+ /* Unknown message type */
+ ogs_error("Unknown message type %d", message->h.type);
+ return OGS_PFCP_ERROR_UNKNOWN_MESSAGE;
+ }
+
+ /* Check requirement vs. tlv_node_id existence */
+ switch (requirement) {
+ case OGS_PFCP_NODE_ID_MANDATORY:
+ /* Must have tlv_node_id. presence must be 1. */
+ ogs_assert(tlv_node_id);
+ if (!tlv_node_id->presence) {
+ status = OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT;
+ goto done;
+ }
+ break;
+
+ case OGS_PFCP_NODE_ID_OPTIONAL:
+ /*
+ * Must have tlv_node_id. presence=1 => real Node ID
+ * presence=0 => no Node ID
+ */
+ ogs_assert(tlv_node_id);
+ if (!tlv_node_id->presence) {
+ status = OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT;
+ goto done;
+ }
+ break;
+
+ case OGS_PFCP_NODE_ID_NONE:
+ /* Must be NULL => no Node ID field */
+ ogs_assert(tlv_node_id == NULL);
+ status = OGS_PFCP_STATUS_NODE_ID_NONE;
+ goto done;
+
+ default:
+ status = OGS_PFCP_ERROR_UNKNOWN_MESSAGE;
+ goto done;
+ }
+
+ memcpy(node_id, tlv_node_id->data, tlv_node_id->len);
+
+ if (node_id->type != OGS_PFCP_NODE_ID_IPV4 &&
+ node_id->type != OGS_PFCP_NODE_ID_IPV6 &&
+ node_id->type != OGS_PFCP_NODE_ID_FQDN) {
+ ogs_error("Semantic incorrect message[%d] type[%d]",
+ message->h.type, node_id->type);
+ return OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE;
+ }
+
+ /* Node ID is valid */
+ status = OGS_PFCP_STATUS_SUCCESS;
+
+done:
+ return status;
+}
+
+ogs_sockaddr_t *ogs_pfcp_node_id_to_addrinfo(const ogs_pfcp_node_id_t *node_id)
+{
+ ogs_sockaddr_t *p;
+ int ret;
+ uint16_t port = ogs_pfcp_self()->pfcp_port;
+ char fqdn[OGS_MAX_FQDN_LEN+1];
+
+ ogs_assert(node_id);
+ switch (node_id->type) {
+
+ /*------------------------------------------------
+ * 1) IPv4
+ *-----------------------------------------------*/
+ case OGS_PFCP_NODE_ID_IPV4:
+ p = (ogs_sockaddr_t *)ogs_calloc(1, sizeof(*p));
+ if (!p) {
+ ogs_error("ogs_calloc() failed");
+ return NULL;
+ }
+ p->sa.sa_family = AF_INET;
+ p->sin.sin_port = htobe16(port);
+ p->sin.sin_addr.s_addr = node_id->addr;
+ p->next = NULL;
+ return p;
+
+ /*------------------------------------------------
+ * 2) IPv6
+ *-----------------------------------------------*/
+ case OGS_PFCP_NODE_ID_IPV6:
+ p = (ogs_sockaddr_t *)ogs_calloc(1, sizeof(*p));
+ if (!p) {
+ ogs_error("ogs_calloc() failed");
+ return NULL;
+ }
+ p->sa.sa_family = AF_INET6;
+ p->sin6.sin6_port = htobe16(port);
+ /* Copy 16 bytes of IPv6 address */
+ memcpy(&p->sin6.sin6_addr, node_id->addr6, 16);
+ p->next = NULL;
+ return p;
+
+ /*------------------------------------------------
+ * 3) FQDN
+ *-----------------------------------------------*/
+ case OGS_PFCP_NODE_ID_FQDN:
+ /* If the FQDN is not empty, we attempt DNS resolution.
+ * ogs_addaddrinfo() is a placeholder for your actual
+ * DNS -> ogs_sockaddr_t function (often wraps getaddrinfo).
+ */
+ /* Port=0 or set as needed, family=AF_UNSPEC, flags=0. */
+ if (ogs_fqdn_parse(fqdn, node_id->fqdn, strlen(node_id->fqdn)) <= 0) {
+ ogs_error("ogs_fqdn_parse() error [%s]", node_id->fqdn);
+ return NULL;
+ }
+ ret = ogs_getaddrinfo(&p, AF_UNSPEC, fqdn, port, 0);
+ if (ret != 0) {
+ /* DNS resolution failed => *out remains NULL */
+ ogs_error("ogs_addaddrinfo() failed");
+ return NULL;
+ }
+ /* If FQDN is empty, just return with no addresses. */
+ return p;
+
+ /*------------------------------------------------
+ * 4) Unsupported type or default
+ *-----------------------------------------------*/
+ default:
+ /* Optionally handle an error or just return success
+ * with no addresses.
+ */
+ ogs_error("Unknown type [%d]", node_id->type);
+ return NULL;
+ }
+}
+
+/* Utility function to convert node_id to string for logging */
+const char *ogs_pfcp_node_id_to_string_static(
+ const ogs_pfcp_node_id_t *node_id)
+{
+ static char buffer[OGS_MAX_FQDN_LEN+1] = { 0, };
+
+ if (node_id) {
+ switch (node_id->type) {
+ case OGS_PFCP_NODE_ID_IPV4:
+ inet_ntop(AF_INET, &node_id->addr, buffer, sizeof(buffer));
+ break;
+ case OGS_PFCP_NODE_ID_IPV6:
+ inet_ntop(AF_INET6, node_id->addr6, buffer, sizeof(buffer));
+ break;
+ case OGS_PFCP_NODE_ID_FQDN:
+ if (ogs_fqdn_parse(buffer,
+ node_id->fqdn,
+ strlen(node_id->fqdn)) <= 0)
+ snprintf(buffer, sizeof(buffer), "%s", node_id->fqdn);
+ break;
+ default:
+ snprintf(buffer, sizeof(buffer), "Unknown");
+ break;
+ }
+ }
+
+ return buffer;
+}
diff --git a/lib/pfcp/util.h b/lib/pfcp/util.h
new file mode 100644
index 000000000..ef6ae5d9a
--- /dev/null
+++ b/lib/pfcp/util.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2025 by Sukchan Lee
+ *
+ * This file is part of Open5GS.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#if !defined(OGS_PFCP_INSIDE) && !defined(OGS_PFCP_COMPILATION)
+#error "This header cannot be included directly."
+#endif
+
+#ifndef OGS_PFCP_UTIL_H
+#define OGS_PFCP_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ /* Success with actual Node ID */
+ OGS_PFCP_STATUS_SUCCESS = 0,
+
+ /* Success with no Node ID (NONE type) */
+ OGS_PFCP_STATUS_NODE_ID_NONE,
+
+ /* Success with OPTIONAL node_id_tlv, but presence=0 */
+ OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT,
+
+ /* Error codes */
+ OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE,
+ OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT,
+ OGS_PFCP_ERROR_NODE_ID_NOT_FOUND,
+ OGS_PFCP_ERROR_UNKNOWN_MESSAGE
+
+} ogs_pfcp_status_e;
+
+ogs_pfcp_status_e
+ogs_pfcp_extract_node_id(ogs_pfcp_message_t *message,
+ ogs_pfcp_node_id_t *node_id);
+
+ogs_sockaddr_t *ogs_pfcp_node_id_to_addrinfo(const ogs_pfcp_node_id_t *node_id);
+const char *ogs_pfcp_node_id_to_string_static(
+ const ogs_pfcp_node_id_t *node_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OGS_PFCP_UTIL_H */
diff --git a/lib/pfcp/xact.c b/lib/pfcp/xact.c
index 30f3f9f12..fbbc2d97c 100644
--- a/lib/pfcp/xact.c
+++ b/lib/pfcp/xact.c
@@ -70,7 +70,6 @@ void ogs_pfcp_xact_final(void)
ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pfcp_xact_t *xact = NULL;
ogs_assert(node);
@@ -109,11 +108,10 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
ogs_list_init(&xact->pdr_to_create_list);
- ogs_debug("[%d] %s Create peer [%s]:%d",
+ ogs_debug("[%d] %s Create peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_sockaddr_to_string_static(node->addr_list));
return xact;
}
@@ -121,7 +119,6 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
static ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
ogs_pfcp_node_t *node, uint32_t sqn)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pfcp_xact_t *xact = NULL;
ogs_assert(node);
@@ -156,11 +153,10 @@ static ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
ogs_list_add(xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
&xact->node->local_list : &xact->node->remote_list, xact);
- ogs_debug("[%d] %s Create peer [%s]:%d",
+ ogs_debug("[%d] %s Create peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_sockaddr_to_string_static(node->addr_list));
return xact;
}
@@ -183,7 +179,6 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_find_by_id(ogs_pool_id_t id)
int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
ogs_pfcp_header_t *hdesc, ogs_pkbuf_t *pkbuf)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pfcp_xact_stage_t stage;
ogs_pfcp_header_t *h = NULL;
int pfcp_hlen = 0;
@@ -193,12 +188,11 @@ int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
ogs_assert(hdesc);
ogs_assert(pkbuf);
- ogs_debug("[%d] %s UPD TX-%d peer [%s]:%d",
+ ogs_debug("[%d] %s UPD TX-%d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
hdesc->type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
stage = ogs_pfcp_xact_get_stage(hdesc->type, xact->xid);
if (xact->org == OGS_PFCP_LOCAL_ORIGINATOR) {
@@ -290,15 +284,13 @@ int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
static int ogs_pfcp_xact_update_rx(ogs_pfcp_xact_t *xact, uint8_t type)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pfcp_xact_stage_t stage;
- ogs_debug("[%d] %s UPD RX-%d peer [%s]:%d",
+ ogs_debug("[%d] %s UPD RX-%d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
stage = ogs_pfcp_xact_get_stage(type, xact->xid);
if (xact->org == OGS_PFCP_LOCAL_ORIGINATOR) {
@@ -325,25 +317,23 @@ static int ogs_pfcp_xact_update_rx(ogs_pfcp_xact_t *xact, uint8_t type)
pfcp.t1_holding_duration);
ogs_warn("[%d] %s Request Duplicated. Retransmit!"
- " for step %d type %d peer [%s]:%d",
+ " for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE",
xact->step, type,
- OGS_ADDR(&xact->node->addr,
- buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(
+ xact->node->addr_list));
ogs_expect(OGS_OK == ogs_pfcp_sendto(xact->node, pkbuf));
} else {
ogs_warn("[%d] %s Request Duplicated. Discard!"
- " for step %d type %d peer [%s]:%d",
+ " for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE",
xact->step, type,
- OGS_ADDR(&xact->node->addr,
- buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(
+ xact->node->addr_list));
}
return OGS_RETRY;
@@ -391,25 +381,23 @@ static int ogs_pfcp_xact_update_rx(ogs_pfcp_xact_t *xact, uint8_t type)
pfcp.t1_holding_duration);
ogs_warn("[%d] %s Request Duplicated. Retransmit!"
- " for step %d type %d peer [%s]:%d",
+ " for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE",
xact->step, type,
- OGS_ADDR(&xact->node->addr,
- buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(
+ xact->node->addr_list));
ogs_expect(OGS_OK == ogs_pfcp_sendto(xact->node, pkbuf));
} else {
ogs_warn("[%d] %s Request Duplicated. Discard!"
- " for step %d type %d peer [%s]:%d",
+ " for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
"LOCAL " : "REMOTE",
xact->step, type,
- OGS_ADDR(&xact->node->addr,
- buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(
+ xact->node->addr_list));
}
return OGS_RETRY;
@@ -462,8 +450,6 @@ static int ogs_pfcp_xact_update_rx(ogs_pfcp_xact_t *xact, uint8_t type)
int ogs_pfcp_xact_commit(ogs_pfcp_xact_t *xact)
{
- char buf[OGS_ADDRSTRLEN];
-
uint8_t type;
ogs_pkbuf_t *pkbuf = NULL;
ogs_pfcp_xact_stage_t stage;
@@ -471,11 +457,10 @@ int ogs_pfcp_xact_commit(ogs_pfcp_xact_t *xact)
ogs_assert(xact);
ogs_assert(xact->node);
- ogs_debug("[%d] %s Commit peer [%s]:%d",
+ ogs_debug("[%d] %s Commit peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
type = xact->seq[xact->step-1].type;
stage = ogs_pfcp_xact_get_stage(type, xact->xid);
@@ -581,7 +566,6 @@ void ogs_pfcp_xact_delayed_commit(ogs_pfcp_xact_t *xact, ogs_time_t duration)
static void response_timeout(void *data)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pool_id_t xact_id = OGS_INVALID_POOL_ID;
ogs_pfcp_xact_t *xact = NULL;
@@ -597,12 +581,11 @@ static void response_timeout(void *data)
ogs_assert(xact->node);
ogs_debug("[%d] %s Response Timeout "
- "for step %d type %d peer [%s]:%d",
+ "for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
xact->step, xact->seq[xact->step-1].type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
if (--xact->response_rcount > 0) {
ogs_pkbuf_t *pkbuf = NULL;
@@ -617,12 +600,11 @@ static void response_timeout(void *data)
ogs_expect(OGS_OK == ogs_pfcp_sendto(xact->node, pkbuf));
} else {
ogs_warn("[%d] %s No Reponse. Give up! "
- "for step %d type %d peer [%s]:%d",
+ "for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
xact->step, xact->seq[xact->step-1].type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
if (xact->cb)
xact->cb(xact, xact->data);
@@ -633,7 +615,6 @@ static void response_timeout(void *data)
static void holding_timeout(void *data)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pool_id_t xact_id = OGS_INVALID_POOL_ID;
ogs_pfcp_xact_t *xact = NULL;
@@ -649,12 +630,11 @@ static void holding_timeout(void *data)
ogs_assert(xact->node);
ogs_debug("[%d] %s Holding Timeout "
- "for step %d type %d peer [%s]:%d",
+ "for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
xact->step, xact->seq[xact->step-1].type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
if (--xact->holding_rcount > 0) {
if (xact->tm_holding)
@@ -662,19 +642,17 @@ static void holding_timeout(void *data)
ogs_local_conf()->time.message.pfcp.t1_holding_duration);
} else {
ogs_debug("[%d] %s Delete Transaction "
- "for step %d type %d peer [%s]:%d",
+ "for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
xact->step, xact->seq[xact->step-1].type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
ogs_pfcp_xact_delete(xact);
}
}
static void delayed_commit_timeout(void *data)
{
- char buf[OGS_ADDRSTRLEN];
ogs_pool_id_t xact_id = OGS_INVALID_POOL_ID;
ogs_pfcp_xact_t *xact = NULL;
@@ -690,12 +668,11 @@ static void delayed_commit_timeout(void *data)
ogs_assert(xact->node);
ogs_debug("[%d] %s Delayed Send Timeout "
- "for step %d type %d peer [%s]:%d",
+ "for step %d type %d peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
xact->step, xact->seq[xact->step-1].type,
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
ogs_pfcp_xact_commit(xact);
}
@@ -704,7 +681,6 @@ int ogs_pfcp_xact_receive(
ogs_pfcp_node_t *node, ogs_pfcp_header_t *h, ogs_pfcp_xact_t **xact)
{
int rv;
- char buf[OGS_ADDRSTRLEN];
uint8_t type;
uint32_t sqn, xid;
@@ -731,35 +707,33 @@ int ogs_pfcp_xact_receive(
list = &node->local_list;
break;
default:
- ogs_error("[%d] Unexpected type %u from PFCP peer [%s]:%d",
- xid, type, OGS_ADDR(&node->addr, buf), OGS_PORT(&node->addr));
+ ogs_error("[%d] Unexpected type %u from PFCP peer %s",
+ xid, type, ogs_sockaddr_to_string_static(node->addr_list));
return OGS_ERROR;
}
ogs_assert(list);
ogs_list_for_each(list, new) {
if (new->xid == xid) {
- ogs_debug("[%d] %s Find peer [%s]:%d",
+ ogs_debug("[%d] %s Find peer %s",
new->xid,
new->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_sockaddr_to_string_static(node->addr_list));
break;
}
}
if (!new) {
- ogs_debug("[%d] Cannot find new type %u from PFCP peer [%s]:%d",
- xid, type, OGS_ADDR(&node->addr, buf), OGS_PORT(&node->addr));
+ ogs_debug("[%d] Cannot find new type %u from PFCP peer %s",
+ xid, type, ogs_sockaddr_to_string_static(node->addr_list));
new = ogs_pfcp_xact_remote_create(node, sqn);
}
ogs_assert(new);
- ogs_debug("[%d] %s Receive peer [%s]:%d",
+ ogs_debug("[%d] %s Receive peer %s",
new->xid,
new->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_sockaddr_to_string_static(node->addr_list));
rv = ogs_pfcp_xact_update_rx(new, type);
if (rv == OGS_ERROR) {
@@ -811,16 +785,13 @@ static ogs_pfcp_xact_stage_t ogs_pfcp_xact_get_stage(uint8_t type, uint32_t xid)
int ogs_pfcp_xact_delete(ogs_pfcp_xact_t *xact)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_assert(xact);
ogs_assert(xact->node);
- ogs_debug("[%d] %s Delete peer [%s]:%d",
+ ogs_debug("[%d] %s Delete peer %s",
xact->xid,
xact->org == OGS_PFCP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
- OGS_ADDR(&xact->node->addr, buf),
- OGS_PORT(&xact->node->addr));
+ ogs_sockaddr_to_string_static(xact->node->addr_list));
if (xact->seq[0].pkbuf)
ogs_pkbuf_free(xact->seq[0].pkbuf);
diff --git a/lib/sbi/client.c b/lib/sbi/client.c
index e40255151..d9fef9bb9 100644
--- a/lib/sbi/client.c
+++ b/lib/sbi/client.c
@@ -129,6 +129,9 @@ ogs_sbi_client_t *ogs_sbi_client_add(
ogs_strdup(ogs_sbi_self()->tls.client.private_key);
if (ogs_sbi_self()->tls.client.cert)
client->cert = ogs_strdup(ogs_sbi_self()->tls.client.cert);
+ if (ogs_sbi_self()->tls.client.sslkeylog)
+ client->sslkeylog =
+ ogs_strdup(ogs_sbi_self()->tls.client.sslkeylog);
ogs_debug("ogs_sbi_client_add [%s]", OpenAPI_uri_scheme_ToString(scheme));
OGS_OBJECT_REF(client);
@@ -212,6 +215,8 @@ void ogs_sbi_client_remove(ogs_sbi_client_t *client)
ogs_free(client->private_key);
if (client->cert)
ogs_free(client->cert);
+ if (client->sslkeylog)
+ ogs_free(client->sslkeylog);
if (client->fqdn)
ogs_free(client->fqdn);
@@ -369,6 +374,26 @@ static char *add_params_to_uri(CURL *easy, char *uri, ogs_hash_t *params)
return uri;
}
+/* User-defined SSL_CTX callback function */
+static CURLcode sslctx_callback(CURL *curl, void *sslctx, void *userdata)
+{
+ SSL_CTX *ctx = (SSL_CTX *)sslctx;
+ ogs_sbi_client_t *client = userdata;
+
+ ogs_assert(ctx);
+ ogs_assert(userdata);
+
+ /* Ensure app data is set for SSL objects */
+ SSL_CTX_set_app_data(ctx, client->sslkeylog);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+ /* Set the SSL Key Log callback */
+ SSL_CTX_set_keylog_callback(ctx, ogs_sbi_keylog_callback);
+#endif
+
+ return CURLE_OK;
+}
+
static connection_t *connection_add(
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
ogs_sbi_request_t *request, void *data)
@@ -459,6 +484,7 @@ static connection_t *connection_add(
curl_easy_setopt(conn->easy, CURLOPT_BUFFERSIZE, OGS_MAX_SDU_LEN);
+ /* HTTPS certificate-related settings */
if (client->scheme == OpenAPI_uri_scheme_https) {
if (client->insecure_skip_verify) {
curl_easy_setopt(conn->easy, CURLOPT_SSL_VERIFYPEER, 0);
@@ -468,13 +494,23 @@ static connection_t *connection_add(
curl_easy_setopt(conn->easy, CURLOPT_CAINFO, client->cacert);
}
+ /* Set private key & certificate */
if (client->private_key && client->cert) {
curl_easy_setopt(conn->easy, CURLOPT_SSLKEY, client->private_key);
curl_easy_setopt(conn->easy, CURLOPT_SSLCERT, client->cert);
}
+
+ if (client->sslkeylog) {
+ /* Set SSL_CTX callback */
+ curl_easy_setopt(conn->easy, CURLOPT_SSL_CTX_FUNCTION,
+ sslctx_callback);
+
+ /* Optionally set additional user data */
+ curl_easy_setopt(conn->easy, CURLOPT_SSL_CTX_DATA, client);
+ }
}
- /* HTTP Method */
+ /* Configure HTTP Method */
if (strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PUT) == 0 ||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PATCH) == 0 ||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_DELETE) == 0 ||
diff --git a/lib/sbi/client.h b/lib/sbi/client.h
index d6687b38e..e9bfbc918 100644
--- a/lib/sbi/client.h
+++ b/lib/sbi/client.h
@@ -80,7 +80,7 @@ typedef struct ogs_sbi_client_s {
OpenAPI_uri_scheme_e scheme;
bool insecure_skip_verify;
- char *cacert, *private_key, *cert;
+ char *cacert, *private_key, *cert, *sslkeylog;
char *fqdn;
uint16_t fqdn_port;
diff --git a/lib/sbi/context.c b/lib/sbi/context.c
index 55bda5a2c..f9740b5de 100644
--- a/lib/sbi/context.c
+++ b/lib/sbi/context.c
@@ -134,56 +134,73 @@ static int ogs_sbi_context_prepare(void)
self.tls.server.scheme = OpenAPI_uri_scheme_http;
self.tls.client.scheme = OpenAPI_uri_scheme_http;
+ /* Initialize delegated config with defaults */
+ self.client_delegated_config.nrf.nfm = OGS_SBI_CLIENT_DELEGATED_AUTO;
+ self.client_delegated_config.nrf.disc = OGS_SBI_CLIENT_DELEGATED_AUTO;
+ self.client_delegated_config.scp.next = OGS_SBI_CLIENT_DELEGATED_AUTO;
+
return OGS_OK;
}
static int ogs_sbi_context_validation(
const char *local, const char *nrf, const char *scp)
{
+#define MAX_MODE 3
+ int i;
+ ogs_sbi_client_delegated_mode_e mode[MAX_MODE];
+
+ ogs_assert(context_initialized == 1);
+
/* If SMF is only used in 4G EPC, no SBI interface is required. */
if (local && strcmp(local, "smf") != 0 && ogs_sbi_server_first() == NULL) {
ogs_error("No %s.sbi.address: in '%s'", local, ogs_app()->file);
return OGS_ERROR;
}
- ogs_assert(context_initialized == 1);
- switch (self.discovery_config.delegated) {
- case OGS_SBI_DISCOVERY_DELEGATED_AUTO:
- if (local && strcmp(local, "nrf") == 0) {
- /* Skip NRF */
- } else if (local && strcmp(local, "scp") == 0) {
- /* Skip SCP */
- } else if (local && strcmp(local, "smf") == 0) {
- /* Skip SMF since SMF can run 4G */
- } else {
- if (NF_INSTANCE_CLIENT(self.nrf_instance) ||
- NF_INSTANCE_CLIENT(self.scp_instance)) {
+ mode[0] = self.client_delegated_config.nrf.nfm;
+ mode[1] = self.client_delegated_config.nrf.disc;
+ mode[2] = self.client_delegated_config.scp.next;
+
+ for (i = 0; i < MAX_MODE; i++) {
+ switch (mode[i]) {
+ case OGS_SBI_CLIENT_DELEGATED_AUTO:
+ if (local && strcmp(local, "nrf") == 0) {
+ /* Skip NRF */
+ } else if (local && strcmp(local, "scp") == 0) {
+ /* Skip SCP */
+ } else if (local && strcmp(local, "smf") == 0) {
+ /* Skip SMF since SMF can run 4G */
} else {
- ogs_error("DELEGATED_AUTO - Both NRF and %s are unavailable",
- scp && strcmp(scp, "next_scp") == 0 ?
+ if (NF_INSTANCE_CLIENT(self.nrf_instance) ||
+ NF_INSTANCE_CLIENT(self.scp_instance)) {
+ } else {
+ ogs_error("[%d] DELEGATED_AUTO - "
+ "Both NRF and %s are unavailable",
+ i, scp && strcmp(scp, "next_scp") == 0 ?
+ "Next-hop SCP" : "SCP");
+ return OGS_ERROR;
+ }
+ }
+ break;
+ case OGS_SBI_CLIENT_DELEGATED_YES:
+ if (NF_INSTANCE_CLIENT(self.scp_instance) == NULL) {
+ ogs_error("[%d] DELEGATED_YES - no %s available",
+ i, scp && strcmp(scp, "next_scp") == 0 ?
"Next-hop SCP" : "SCP");
return OGS_ERROR;
}
+ break;
+ case OGS_SBI_CLIENT_DELEGATED_NO:
+ if (NF_INSTANCE_CLIENT(self.nrf_instance) == NULL) {
+ ogs_error("[%d] DELEGATED_NO - no NRF available", i);
+ return OGS_ERROR;
+ }
+ break;
+ default:
+ ogs_fatal("[%d] Invalid dicovery-config delegated [%d]",
+ i, mode[i]);
+ ogs_assert_if_reached();
}
- break;
- case OGS_SBI_DISCOVERY_DELEGATED_YES:
- if (NF_INSTANCE_CLIENT(self.scp_instance) == NULL) {
- ogs_error("DELEGATED_YES - no %s available",
- scp && strcmp(scp, "next_scp") == 0 ?
- "Next-hop SCP" : "SCP");
- return OGS_ERROR;
- }
- break;
- case OGS_SBI_DISCOVERY_DELEGATED_NO:
- if (NF_INSTANCE_CLIENT(self.nrf_instance) == NULL) {
- ogs_error("DELEGATED_NO - no NRF available");
- return OGS_ERROR;
- }
- break;
- default:
- ogs_fatal("Invalid dicovery-config delegated [%d]",
- self.discovery_config.delegated);
- ogs_assert_if_reached();
}
if (ogs_sbi_self()->tls.server.scheme == OpenAPI_uri_scheme_https) {
@@ -281,6 +298,11 @@ int ogs_sbi_context_parse_config(
self.tls.server.cert =
ogs_yaml_iter_value(
&server_iter);
+ } else if (!strcmp(server_key,
+ "sslkeylogfile")) {
+ self.tls.server.sslkeylog =
+ ogs_yaml_iter_value(
+ &server_iter);
} else if (!strcmp(server_key,
"verify_client")) {
self.tls.server.verify_client =
@@ -340,6 +362,11 @@ int ogs_sbi_context_parse_config(
self.tls.client.cert =
ogs_yaml_iter_value(
&client_iter);
+ } else if (!strcmp(client_key,
+ "client_sslkeylogfile")) {
+ self.tls.client.sslkeylog =
+ ogs_yaml_iter_value(
+ &client_iter);
}
}
}
@@ -481,6 +508,115 @@ int ogs_sbi_context_parse_config(
} while (ogs_yaml_iter_type(&scp_array) ==
YAML_SEQUENCE_NODE);
}
+ /* Parse delegated section */
+ else if (!strcmp(client_key, "delegated")) {
+ ogs_yaml_iter_t delegated_iter;
+ ogs_yaml_iter_recurse(&client_iter,
+ &delegated_iter);
+
+ while (ogs_yaml_iter_next(
+ &delegated_iter)) {
+ const char *del_key =
+ ogs_yaml_iter_key(
+ &delegated_iter);
+ if (!strcmp(del_key, "nrf")) {
+ ogs_yaml_iter_t nrf_iter;
+ ogs_yaml_iter_recurse(
+ &delegated_iter, &nrf_iter);
+ while (ogs_yaml_iter_next(
+ &nrf_iter)) {
+ const char *nrf_key =
+ ogs_yaml_iter_key(
+ &nrf_iter);
+ const char *nrf_val =
+ ogs_yaml_iter_value(
+ &nrf_iter);
+ ogs_assert(nrf_key);
+
+ if (!strcmp(nrf_key,"nfm")) {
+ if (!strcmp(nrf_val,"no")) {
+ self.client_delegated_config.nrf.nfm =
+ OGS_SBI_CLIENT_DELEGATED_NO;
+ } else if (!strcmp(
+ nrf_val,"yes")) {
+ self.client_delegated_config.nrf.nfm =
+ OGS_SBI_CLIENT_DELEGATED_YES;
+ } else if (!strcmp(
+ nrf_val,"auto")) {
+ self.client_delegated_config.nrf.nfm =
+ OGS_SBI_CLIENT_DELEGATED_AUTO;
+ } else {
+ ogs_warn("unknown "
+ "'nfm' `%s`",
+ nrf_val);
+ }
+ } else if (!strcmp(
+ nrf_key,"disc")) {
+ if (!strcmp(nrf_val,"no")) {
+ self.client_delegated_config.nrf.disc =
+ OGS_SBI_CLIENT_DELEGATED_NO;
+ } else if (!strcmp(
+ nrf_val,"yes")) {
+ self.client_delegated_config.nrf.disc =
+ OGS_SBI_CLIENT_DELEGATED_YES;
+ } else if (!strcmp(
+ nrf_val,"auto")) {
+ self.client_delegated_config.nrf.disc =
+ OGS_SBI_CLIENT_DELEGATED_AUTO;
+ } else {
+ ogs_warn("unknown "
+ "'disc' `%s`",
+ nrf_val);
+ }
+ } else {
+ ogs_warn("unknown nrf "
+ "delegated key `%s`",
+ nrf_key);
+ }
+ }
+ } else if (!strcmp(del_key, "scp")) {
+ ogs_yaml_iter_t scp_iter;
+ ogs_yaml_iter_recurse(
+ &delegated_iter, &scp_iter);
+ while (ogs_yaml_iter_next(
+ &scp_iter)) {
+ const char *scp_key =
+ ogs_yaml_iter_key(
+ &scp_iter);
+ const char *scp_val =
+ ogs_yaml_iter_value(
+ &scp_iter);
+ ogs_assert(scp_key);
+
+ if (!strcmp(scp_key,"next")) {
+ if (!strcmp(scp_val,"no")) {
+ self.client_delegated_config.scp.next =
+ OGS_SBI_CLIENT_DELEGATED_NO;
+ } else if (!strcmp(
+ scp_val,"yes")) {
+ self.client_delegated_config.scp.next =
+ OGS_SBI_CLIENT_DELEGATED_YES;
+ } else if (!strcmp(
+ scp_val,"auto")) {
+ self.client_delegated_config.scp.next =
+ OGS_SBI_CLIENT_DELEGATED_AUTO;
+ } else {
+ ogs_warn("unknown "
+ "'next' `%s`",
+ scp_val);
+ }
+ } else {
+ ogs_warn("unknown scp "
+ "delegated key `%s`",
+ scp_key);
+ }
+ }
+ } else {
+ ogs_warn("unknown delegated "
+ "key `%s`", del_key);
+ }
+ }
+ }
}
} else
ogs_warn("unknown key `%s`", sbi_key);
@@ -507,52 +643,6 @@ int ogs_sbi_context_parse_config(
} while (ogs_yaml_iter_type(
&service_name_iter) == YAML_SEQUENCE_NODE);
- } else if (!strcmp(local_key, "discovery")) {
- ogs_yaml_iter_t discovery_iter;
- ogs_yaml_iter_recurse(&local_iter, &discovery_iter);
- while (ogs_yaml_iter_next(&discovery_iter)) {
- const char *discovery_key =
- ogs_yaml_iter_key(&discovery_iter);
- ogs_assert(discovery_key);
- if (!strcmp(discovery_key, "delegated")) {
- const char *delegated =
- ogs_yaml_iter_value(&discovery_iter);
- if (!strcmp(delegated, "auto"))
- self.discovery_config.delegated =
- OGS_SBI_DISCOVERY_DELEGATED_AUTO;
- else if (!strcmp(delegated, "yes"))
- self.discovery_config.delegated =
- OGS_SBI_DISCOVERY_DELEGATED_YES;
- else if (!strcmp(delegated, "no"))
- self.discovery_config.delegated =
- OGS_SBI_DISCOVERY_DELEGATED_NO;
- else
- ogs_warn("unknown 'delegated' value `%s`",
- delegated);
- } else if (!strcmp(discovery_key, "option")) {
- ogs_yaml_iter_t option_iter;
- ogs_yaml_iter_recurse(
- &discovery_iter, &option_iter);
-
- while (ogs_yaml_iter_next(&option_iter)) {
- const char *option_key =
- ogs_yaml_iter_key(&option_iter);
- ogs_assert(option_key);
-
- if (!strcmp(option_key, "no_service_names")) {
- self.discovery_config.no_service_names =
- ogs_yaml_iter_bool(&option_iter);
- } else if (!strcmp(option_key,
- "prefer_requester_nf_instance_id")) {
- self.discovery_config.
- prefer_requester_nf_instance_id =
- ogs_yaml_iter_bool(&option_iter);
- } else
- ogs_warn("unknown key `%s`", option_key);
- }
- } else
- ogs_warn("unknown key `%s`", discovery_key);
- }
}
}
}
@@ -664,7 +754,7 @@ int ogs_sbi_context_parse_server_config(
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
- const char *private_key = NULL, *cert = NULL;
+ const char *private_key = NULL, *cert = NULL, *sslkeylog = NULL;
bool verify_client = false;
const char *verify_client_cacert = NULL;
@@ -759,6 +849,8 @@ int ogs_sbi_context_parse_server_config(
private_key = ogs_yaml_iter_value(&server_iter);
} else if (!strcmp(server_key, "cert")) {
cert = ogs_yaml_iter_value(&server_iter);
+ } else if (!strcmp(server_key, "sslkeylogfile")) {
+ sslkeylog = ogs_yaml_iter_value(&server_iter);
} else if (!strcmp(server_key, "verify_client")) {
verify_client = ogs_yaml_iter_bool(&server_iter);
} else if (!strcmp(server_key, "verify_client_cacert")) {
@@ -811,9 +903,38 @@ int ogs_sbi_context_parse_server_config(
}
addr = NULL;
+ /* ----- Process advertise (Host+Port Parsing Logic) ----- */
for (i = 0; i < num_of_advertise; i++) {
- rv = ogs_addaddrinfo(&addr, family, advertise[i], port, 0);
+ uint16_t adv_port = port; /* Default to server's port */
+ char *hostbuf = NULL;
+ const char *colon_pos = strchr(advertise[i], ':');
+
+ if (colon_pos) {
+ /* If a colon exists, split host and port */
+ size_t host_len = colon_pos - advertise[i];
+
+ /* Allocate memory for the host part */
+ hostbuf = (char *)ogs_malloc(host_len + 1);
+ ogs_assert(hostbuf);
+
+ /* Copy the host part into hostbuf */
+ memcpy(hostbuf, advertise[i], host_len);
+ hostbuf[host_len] = '\0';
+
+ /* Parse the port part */
+ adv_port = (uint16_t)atoi(colon_pos + 1);
+ } else {
+ /* If no colon, treat the entire string as the host */
+ hostbuf = ogs_strdup(advertise[i]);
+ ogs_assert(hostbuf);
+ }
+
+ /* Add the parsed address info */
+ rv = ogs_addaddrinfo(&addr, family, hostbuf, adv_port, 0);
ogs_assert(rv == OGS_OK);
+
+ /* Free the allocated memory */
+ ogs_free(hostbuf);
}
node = ogs_list_first(&list);
@@ -853,6 +974,12 @@ int ogs_sbi_context_parse_server_config(
server->cert = ogs_strdup(cert);
ogs_assert(server->cert);
}
+ if (sslkeylog) {
+ if (server->sslkeylog)
+ ogs_free(server->sslkeylog);
+ server->sslkeylog = ogs_strdup(sslkeylog);
+ ogs_assert(server->sslkeylog);
+ }
if (scheme == OpenAPI_uri_scheme_https) {
if (!server->private_key) {
@@ -902,6 +1029,12 @@ int ogs_sbi_context_parse_server_config(
server->cert = ogs_strdup(cert);
ogs_assert(server->cert);
}
+ if (sslkeylog) {
+ if (server->sslkeylog)
+ ogs_free(server->sslkeylog);
+ server->sslkeylog = ogs_strdup(sslkeylog);
+ ogs_assert(server->sslkeylog);
+ }
if (scheme == OpenAPI_uri_scheme_https) {
if (!server->private_key) {
@@ -939,6 +1072,7 @@ ogs_sbi_client_t *ogs_sbi_context_parse_client_config(ogs_yaml_iter_t *iter)
const char *client_private_key = NULL;
const char *client_cert = NULL;
+ const char *client_sslkeylog = NULL;
bool rc;
@@ -980,6 +1114,8 @@ ogs_sbi_client_t *ogs_sbi_context_parse_client_config(ogs_yaml_iter_t *iter)
client_private_key = ogs_yaml_iter_value(iter);
} else if (!strcmp(key, "client_cert")) {
client_cert = ogs_yaml_iter_value(iter);
+ } else if (!strcmp(key, "client_sslkeylogfile")) {
+ client_sslkeylog = ogs_yaml_iter_value(iter);
}
}
@@ -1049,6 +1185,13 @@ ogs_sbi_client_t *ogs_sbi_context_parse_client_config(ogs_yaml_iter_t *iter)
ogs_assert(client->cert);
}
+ if (client_sslkeylog) {
+ if (client->sslkeylog)
+ ogs_free(client->sslkeylog);
+ client->sslkeylog = ogs_strdup(client_sslkeylog);
+ ogs_assert(client->sslkeylog);
+ }
+
if ((!client_private_key && client_cert) ||
(client_private_key && !client_cert)) {
ogs_error("Either the private key or certificate is missing.");
@@ -1721,11 +1864,8 @@ void ogs_sbi_nf_instance_build_default(ogs_sbi_nf_instance_t *nf_instance)
ogs_assert(advertise);
/* First FQDN is selected */
- if (!hostname) {
+ if (!hostname)
hostname = ogs_gethostname(advertise);
- if (hostname)
- continue;
- }
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
ogs_sockaddr_t *addr = NULL;
@@ -1795,11 +1935,8 @@ ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
ogs_assert(advertise);
/* First FQDN is selected */
- if (!hostname) {
+ if (!hostname)
hostname = ogs_gethostname(advertise);
- if (hostname)
- continue;
- }
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
bool is_port = true;
@@ -1912,6 +2049,7 @@ static void nf_service_associate_client(ogs_sbi_nf_service_t *nf_service)
{
ogs_sbi_client_t *client = NULL;
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
+ uint16_t port = 0;
ogs_assert(nf_service->scheme);
@@ -1919,15 +2057,28 @@ static void nf_service_associate_client(ogs_sbi_nf_service_t *nf_service)
if (nf_service->num_of_addr) {
addr = nf_service->addr[0].ipv4;
addr6 = nf_service->addr[0].ipv6;
+
+ /*
+ * Added support for using custom port numbers with FQDN.
+ *
+ * This code checks if a user-defined port number is provided in the
+ * NFService structure. If the is_port flag is set, the port is
+ * assigned the specified value.
+ *
+ * This ensures that services using non-default ports can be accessed
+ * correctly, regardless of whether TLS is enabled or not.
+ */
+ if (nf_service->addr[0].is_port)
+ port = nf_service->addr[0].port;
}
if (nf_service->fqdn || addr || addr6) {
client = ogs_sbi_client_find(
- nf_service->scheme, nf_service->fqdn, 0, addr, addr6);
+ nf_service->scheme, nf_service->fqdn, port, addr, addr6);
if (!client) {
ogs_debug("%s: ogs_sbi_client_add()", OGS_FUNC);
client = ogs_sbi_client_add(
- nf_service->scheme, nf_service->fqdn, 0, addr, addr6);
+ nf_service->scheme, nf_service->fqdn, port, addr, addr6);
if (!client) {
ogs_error("%s: ogs_sbi_client_add() failed", OGS_FUNC);
return;
@@ -2539,6 +2690,9 @@ void ogs_sbi_subscription_data_remove(
if (subscription_data->subscr_cond.service_name)
ogs_free(subscription_data->subscr_cond.service_name);
+
+ if (subscription_data->subscr_cond.nf_instance_id)
+ ogs_free(subscription_data->subscr_cond.nf_instance_id);
if (subscription_data->t_validity)
ogs_timer_delete(subscription_data->t_validity);
@@ -2691,3 +2845,29 @@ bool ogs_sbi_fqdn_in_vplmn(char *fqdn)
return false;
}
+
+/* OpenSSL Key Log Callback */
+void ogs_sbi_keylog_callback(const SSL *ssl, const char *line)
+{
+ SSL_CTX *ctx = NULL;
+ FILE *file = NULL;
+ const char *sslkeylog_file = NULL;
+
+ ogs_assert(ssl);
+ ogs_assert(line);
+
+ /* Retrieve SSL_CTX from SSL object */
+ ctx = SSL_get_SSL_CTX(ssl);
+ ogs_assert(ctx);
+
+ sslkeylog_file = (const char *)SSL_CTX_get_app_data(ctx);
+ ogs_assert(sslkeylog_file);
+
+ file = fopen(sslkeylog_file, "a");
+ if (file) {
+ fprintf(file, "%s\n", line);
+ fclose(file);
+ } else {
+ ogs_error("Failed to open SSL key log file: %s", sslkeylog_file);
+ }
+}
diff --git a/lib/sbi/context.h b/lib/sbi/context.h
index 326fa46b7..6d156adfd 100644
--- a/lib/sbi/context.h
+++ b/lib/sbi/context.h
@@ -36,19 +36,25 @@ typedef struct ogs_sbi_smf_info_s ogs_sbi_smf_info_t;
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
typedef enum {
- OGS_SBI_DISCOVERY_DELEGATED_AUTO = 0,
- OGS_SBI_DISCOVERY_DELEGATED_YES,
- OGS_SBI_DISCOVERY_DELEGATED_NO,
-} ogs_sbi_discovery_delegated_mode;
+ OGS_SBI_CLIENT_DELEGATED_AUTO = 0,
+ OGS_SBI_CLIENT_DELEGATED_YES,
+ OGS_SBI_CLIENT_DELEGATED_NO,
+} ogs_sbi_client_delegated_mode_e;
-typedef struct ogs_sbi_discovery_config_s {
- ogs_sbi_discovery_delegated_mode delegated;
- bool no_service_names;
- bool prefer_requester_nf_instance_id;
-} ogs_sbi_discovery_config_t;
+/* To hold all delegated config under sbi.client.delegated */
+typedef struct ogs_sbi_client_delegated_config_s {
+ struct {
+ ogs_sbi_client_delegated_mode_e nfm; /* e.g. Registration, Heartbeat */
+ ogs_sbi_client_delegated_mode_e disc; /* NF discovery */
+ } nrf;
+ struct {
+ ogs_sbi_client_delegated_mode_e next; /* Next-hop SCP delegation */
+ } scp;
+} ogs_sbi_client_delegated_config_t;
typedef struct ogs_sbi_context_s {
- ogs_sbi_discovery_config_t discovery_config; /* SCP Discovery Delegated */
+ /* For sbi.client.delegated */
+ ogs_sbi_client_delegated_config_t client_delegated_config;
#define OGS_HOME_NETWORK_PKI_VALUE_MIN 1
#define OGS_HOME_NETWORK_PKI_VALUE_MAX 254
@@ -65,6 +71,7 @@ typedef struct ogs_sbi_context_s {
const char *private_key;
const char *cert;
+ const char *sslkeylog;
bool verify_client;
const char *verify_client_cacert;
@@ -77,6 +84,7 @@ typedef struct ogs_sbi_context_s {
const char *private_key;
const char *cert;
+ const char *sslkeylog;
} client;
} tls;
@@ -300,6 +308,7 @@ typedef struct ogs_sbi_subscription_data_s {
struct {
OpenAPI_nf_type_e nf_type; /* nfType */
char *service_name; /* ServiceName */
+ char *nf_instance_id; /* NF Instance Id */
} subscr_cond;
uint64_t requester_features;
@@ -573,6 +582,8 @@ bool ogs_sbi_supi_in_vplmn(char *supi);
bool ogs_sbi_plmn_id_in_vplmn(ogs_plmn_id_t *plmn_id);
bool ogs_sbi_fqdn_in_vplmn(char *fqdn);
+void ogs_sbi_keylog_callback(const SSL *ssl, const char *line);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/sbi/conv.c b/lib/sbi/conv.c
index 0950f2d8f..5c51ee530 100644
--- a/lib/sbi/conv.c
+++ b/lib/sbi/conv.c
@@ -103,7 +103,7 @@ char *ogs_supi_from_suci(char *suci)
p = tmp;
i = 0;
- while((array[i++] = strsep(&p, "-"))) {
+ while((i < MAX_SUCI_TOKEN) && (array[i++] = strsep(&p, "-"))) {
/* Empty Body */
}
@@ -728,12 +728,12 @@ char *ogs_sbi_bitrate_to_string(uint64_t bitrate, int unit)
uint64_t ogs_sbi_bitrate_from_string(char *str)
{
char *unit = NULL;
- uint64_t bitrate = 0;
+ double bitrate = 0;
ogs_assert(str);
uint64_t mul = 1;
unit = strrchr(str, ' ');
- bitrate = atoll(str);
+ bitrate = atof(str);
if (!unit) {
ogs_error("No Unit [%s]", str);
@@ -761,7 +761,7 @@ uint64_t ogs_sbi_bitrate_from_string(char *str)
else
bitrate *= mul;
- return bitrate;
+ return (uint64_t) bitrate;
}
#define MAX_TIMESTR_LEN 128
@@ -1211,6 +1211,35 @@ void ogs_sbi_free_plmn_list(OpenAPI_list_t *PlmnList)
OpenAPI_list_free(PlmnList);
}
+/**
+ * Compares an ogs_plmn_id_t structure with an OpenAPI_plmn_id_t structure.
+ *
+ * @param plmn_list The PLMN-ID in ogs_plmn_id_t format.
+ * @param PlmnList The PLMN-ID in OpenAPI_plmn_id_t format.
+ * @return true if the PLMN-IDs are equal; otherwise, false.
+ */
+bool ogs_sbi_compare_plmn_list(
+ ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId)
+{
+ ogs_plmn_id_t temp_plmn_id;
+
+ ogs_assert(plmn_id);
+ ogs_assert(PlmnId);
+ ogs_assert(PlmnId->mcc);
+ ogs_assert(PlmnId->mnc);
+
+ /* Convert OpenAPI_plmn_id_t to ogs_plmn_id_t */
+ ogs_sbi_parse_plmn_id(&temp_plmn_id, PlmnId);
+
+ /* Compare MCC and MNC values */
+ if (ogs_plmn_id_mcc(plmn_id) == ogs_plmn_id_mcc(&temp_plmn_id) &&
+ ogs_plmn_id_mnc(plmn_id) == ogs_plmn_id_mnc(&temp_plmn_id)) {
+ return true;
+ }
+
+ return false;
+}
+
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id)
{
OpenAPI_plmn_id_nid_t *PlmnIdNid = NULL;
diff --git a/lib/sbi/conv.h b/lib/sbi/conv.h
index dc01e3069..6a7d055f7 100644
--- a/lib/sbi/conv.h
+++ b/lib/sbi/conv.h
@@ -98,6 +98,8 @@ OpenAPI_list_t *ogs_sbi_build_plmn_list(
int ogs_sbi_parse_plmn_list(
ogs_plmn_id_t *plmn_list, OpenAPI_list_t *PlmnList);
void ogs_sbi_free_plmn_list(OpenAPI_list_t *PlmnList);
+bool ogs_sbi_compare_plmn_list(
+ ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId);
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id);
bool ogs_sbi_parse_plmn_id_nid(
diff --git a/lib/sbi/message.c b/lib/sbi/message.c
index 4596004d3..9c591b57a 100644
--- a/lib/sbi/message.c
+++ b/lib/sbi/message.c
@@ -434,8 +434,7 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
&discovery_option->guami.amf_id));
}
}
- if (ogs_sbi_self()->discovery_config.no_service_names == false &&
- discovery_option->num_of_service_names) {
+ if (discovery_option->num_of_service_names) {
/*
* Issues #1730
diff --git a/lib/sbi/message.h b/lib/sbi/message.h
index 7fbad0c03..9e328337f 100644
--- a/lib/sbi/message.h
+++ b/lib/sbi/message.h
@@ -153,6 +153,7 @@ extern "C" {
#define OGS_SBI_PATCH_PATH_NF_STATUS "/nfStatus"
#define OGS_SBI_PATCH_PATH_LOAD "/load"
+#define OGS_SBI_PATCH_PATH_PLMN_LIST "/plmnList"
#define OGS_SBI_PATCH_PATH_VALIDITY_TIME "/validityTime"
diff --git a/lib/sbi/nghttp2-server.c b/lib/sbi/nghttp2-server.c
index de8cc2a1c..9fcbd108d 100644
--- a/lib/sbi/nghttp2-server.c
+++ b/lib/sbi/nghttp2-server.c
@@ -196,7 +196,9 @@ static int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max)
#endif /* OPENSSL_VERSION_NUMBER >= 0x1010000fL */
}
-static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file)
+static SSL_CTX *create_ssl_ctx(
+ const char *key_file, const char *cert_file,
+ const char *sslkeylog_file)
{
SSL_CTX *ssl_ctx;
uint64_t ssl_opts;
@@ -210,6 +212,16 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file)
return NULL;
}
+ /* Set key log files for each SSL_CTX */
+ if (sslkeylog_file) {
+ /* Ensure app data is set for SSL objects */
+ SSL_CTX_set_app_data(ssl_ctx, sslkeylog_file);
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+ /* Set the SSL Key Log callback */
+ SSL_CTX_set_keylog_callback(ssl_ctx, ogs_sbi_keylog_callback);
+#endif
+ }
+
ssl_opts = (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) |
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
@@ -322,7 +334,8 @@ static int server_start(ogs_sbi_server_t *server,
/* Create SSL CTX */
if (server->scheme == OpenAPI_uri_scheme_https) {
- server->ssl_ctx = create_ssl_ctx(server->private_key, server->cert);
+ server->ssl_ctx = create_ssl_ctx(
+ server->private_key, server->cert, server->sslkeylog);
if (!server->ssl_ctx) {
ogs_error("Cannot create SSL CTX");
return OGS_ERROR;
diff --git a/lib/sbi/nnrf-build.c b/lib/sbi/nnrf-build.c
index 71c3d2d09..84bf5c33b 100644
--- a/lib/sbi/nnrf-build.c
+++ b/lib/sbi/nnrf-build.c
@@ -61,6 +61,28 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void)
goto end;
}
+ /*
+ * TS29510
+ * 6.1.6.2 Structured data types
+ * 6.1.6.2.2 Type: NFProfile
+ * Table 6.1.6.2.2-1: Definition of type NFProfile
+ *
+ * NF Profile Changes Support Indicator.
+ * See Annex B.
+ *
+ * This IE may be present in the NFRegister or
+ * NFUpdate (NF Profile Complete Replacement)
+ * request and shall be absent in the response.
+ *
+ * true: the NF Service Consumer supports receiving
+ * NF Profile Changes in the response.
+ *
+ * false (default): the NF Service Consumer does not
+ * support receiving NF Profile Changes in the response.
+ */
+ NFProfile->is_nf_profile_changes_support_ind = true;
+ NFProfile->nf_profile_changes_support_ind = true;
+
message.NFProfile = NFProfile;
request = ogs_sbi_build_request(&message);
@@ -146,9 +168,6 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
OpenAPI_list_free(PlmnIdList);
}
- NFProfile->is_nf_profile_changes_support_ind = true;
- NFProfile->nf_profile_changes_support_ind = true;
-
if (nf_instance->fqdn)
NFProfile->fqdn = ogs_strdup(nf_instance->fqdn);
diff --git a/lib/sbi/nnrf-path.c b/lib/sbi/nnrf-path.c
index 957f633e2..3ecf5ba7e 100644
--- a/lib/sbi/nnrf-path.c
+++ b/lib/sbi/nnrf-path.c
@@ -32,8 +32,9 @@ bool ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, nf_instance);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, nf_instance);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
@@ -54,8 +55,9 @@ bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance)
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, nf_instance);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, nf_instance);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
@@ -76,8 +78,9 @@ bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance)
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, nf_instance);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, nf_instance);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
@@ -120,8 +123,9 @@ bool ogs_nnrf_nfm_send_nf_status_subscribe(
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, subscription_data);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, subscription_data);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
@@ -143,8 +147,9 @@ bool ogs_nnrf_nfm_send_nf_status_update(
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, subscription_data);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, subscription_data);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
@@ -166,8 +171,9 @@ bool ogs_nnrf_nfm_send_nf_status_unsubscribe(
return false;
}
- rc = ogs_sbi_send_notification_request(
- OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL, request, subscription_data);
+ rc = ogs_sbi_send_request_to_nrf(
+ OGS_SBI_SERVICE_TYPE_NNRF_NFM, NULL,
+ ogs_sbi_client_handler, request, subscription_data);
ogs_expect(rc == true);
ogs_sbi_request_free(request);
diff --git a/lib/sbi/path.c b/lib/sbi/path.c
index 0180c450c..4c8c50e67 100644
--- a/lib/sbi/path.c
+++ b/lib/sbi/path.c
@@ -273,11 +273,11 @@ int ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact)
discovery_option = xact->discovery_option;
/* SCP Availability */
- if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_AUTO) {
+ if (ogs_sbi_self()->client_delegated_config.nrf.disc ==
+ OGS_SBI_CLIENT_DELEGATED_AUTO) {
scp_client = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
- } else if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_YES) {
+ } else if (ogs_sbi_self()->client_delegated_config.nrf.disc ==
+ OGS_SBI_CLIENT_DELEGATED_YES) {
scp_client = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
ogs_assert(scp_client);
}
@@ -794,63 +794,88 @@ bool ogs_sbi_send_request_to_client(
return rc;
}
-bool ogs_sbi_send_notification_request(
- ogs_sbi_service_type_e service_type,
+bool ogs_sbi_send_request_to_nrf(
+ ogs_sbi_service_type_e nrf_service_type,
ogs_sbi_discovery_option_t *discovery_option,
+ ogs_sbi_client_cb_f client_cb,
ogs_sbi_request_t *request, void *data)
{
bool rc;
- ogs_sbi_client_t *client = NULL, *scp_client = NULL;
- OpenAPI_nf_type_e target_nf_type = OpenAPI_nf_type_NULL;
+ ogs_sbi_client_t *nrf_client = NULL, *scp_client = NULL;
+ ogs_sbi_client_delegated_mode_e mode = OGS_SBI_CLIENT_DELEGATED_AUTO;
- ogs_assert(service_type);
- target_nf_type = ogs_sbi_service_type_to_nf_type(service_type);
- ogs_assert(target_nf_type);
+ ogs_assert(nrf_service_type);
ogs_assert(request);
scp_client = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
- if (target_nf_type == OpenAPI_nf_type_NRF)
- client = NF_INSTANCE_CLIENT(ogs_sbi_self()->nrf_instance);
- else {
- ogs_fatal("Not implemented[%s]",
- ogs_sbi_service_type_to_name(service_type));
- ogs_assert_if_reached();
- }
+ nrf_client = NF_INSTANCE_CLIENT(ogs_sbi_self()->nrf_instance);
- if (scp_client) {
- /*************************
- * INDIRECT COMMUNICATION
- *************************/
- build_default_discovery_parameter(
- request, service_type, discovery_option);
+ /* Decide which delegated mode to use */
+ if (nrf_service_type == OGS_SBI_SERVICE_TYPE_NNRF_NFM)
+ mode = ogs_sbi_self()->client_delegated_config.nrf.nfm;
+ else if (nrf_service_type == OGS_SBI_SERVICE_TYPE_NNRF_DISC)
+ mode = ogs_sbi_self()->client_delegated_config.nrf.disc;
+ /* else if it's some other Nnrf service, fallback to AUTO or keep default */
- rc = ogs_sbi_client_send_via_scp_or_sepp(
- scp_client, ogs_sbi_client_handler, request, data);
- ogs_expect(rc == true);
-
- } else if (client) {
-
- /***********************
- * DIRECT COMMUNICATION
- ***********************/
-
- /* NRF is available */
- rc = ogs_sbi_client_send_request(
- client, ogs_sbi_client_handler, request, data);
- ogs_expect(rc == true);
-
-
- } else {
- ogs_fatal("[%s:%s] Cannot send request [%s:%s:%s]",
- client ? "CLIENT" : "No-CLIENT",
- scp_client ? "SCP" : "No-SCP",
- ogs_sbi_service_type_to_name(service_type),
+ switch (mode) {
+ case OGS_SBI_CLIENT_DELEGATED_NO:
+ /* NO => Direct communication (NRF must exist) */
+ if (!nrf_client) {
+ ogs_fatal("[No-NRF] Cannot send request [%s:%s:%s]",
+ ogs_sbi_service_type_to_name(nrf_service_type),
request->h.service.name, request->h.api.version);
- rc = false;
- ogs_assert_if_reached();
+ ogs_assert_if_reached();
+ return false;
+ }
+ /* Send directly to NRF */
+ rc = ogs_sbi_client_send_request(nrf_client, client_cb,
+ request, data);
+ ogs_expect(rc == true);
+ break;
+
+ case OGS_SBI_CLIENT_DELEGATED_YES:
+ /* YES => Indirect communication (SCP must exist) */
+ if (!scp_client) {
+ ogs_fatal("[No-SCP] Cannot send request [%s:%s:%s]",
+ ogs_sbi_service_type_to_name(nrf_service_type),
+ request->h.service.name, request->h.api.version);
+ ogs_assert_if_reached();
+ return false;
+ }
+ /* Indirect via SCP, build discovery parameter if needed */
+ build_default_discovery_parameter(request, nrf_service_type,
+ discovery_option);
+ rc = ogs_sbi_client_send_via_scp_or_sepp(scp_client, client_cb,
+ request, data);
+ ogs_expect(rc == true);
+ break;
+
+ case OGS_SBI_CLIENT_DELEGATED_AUTO:
+ default:
+ /*
+ * AUTO => If SCP is present, use it; otherwise direct.
+ */
+ if (scp_client) {
+ build_default_discovery_parameter(request, nrf_service_type,
+ discovery_option);
+ rc = ogs_sbi_client_send_via_scp_or_sepp(scp_client, client_cb,
+ request, data);
+ ogs_expect(rc == true);
+ } else if (nrf_client) {
+ rc = ogs_sbi_client_send_request(nrf_client, client_cb,
+ request, data);
+ ogs_expect(rc == true);
+ } else {
+ ogs_fatal("[No-NRF:No-SCP] Cannot send request [%s:%s:%s]",
+ ogs_sbi_service_type_to_name(nrf_service_type),
+ request->h.service.name, request->h.api.version);
+ ogs_assert_if_reached();
+ return false;
+ }
+ break;
}
- return true;
+ return rc;
}
bool ogs_sbi_send_response(ogs_sbi_stream_t *stream, int status)
@@ -1024,9 +1049,7 @@ static void build_default_discovery_parameter(
OGS_SBI_CUSTOM_DISCOVERY_REQUESTER_NF_INSTANCE_ID,
discovery_option->requester_nf_instance_id);
}
- if (ogs_sbi_self()->discovery_config.
- no_service_names == false &&
- discovery_option->num_of_service_names) {
+ if (discovery_option->num_of_service_names) {
bool rc = false;
/* send array items separated by a comma */
diff --git a/lib/sbi/path.h b/lib/sbi/path.h
index 3aba3f11c..908bd5c11 100644
--- a/lib/sbi/path.h
+++ b/lib/sbi/path.h
@@ -40,9 +40,10 @@ bool ogs_sbi_send_request_with_sepp_discovery(
bool ogs_sbi_send_request_to_client(
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
ogs_sbi_request_t *request, void *data);
-bool ogs_sbi_send_notification_request(
- ogs_sbi_service_type_e service_type,
+bool ogs_sbi_send_request_to_nrf(
+ ogs_sbi_service_type_e nrf_service_type,
ogs_sbi_discovery_option_t *discovery_option,
+ ogs_sbi_client_cb_f client_cb,
ogs_sbi_request_t *request, void *data);
#define ogs_sbi_send_http_status_no_content(__sTREAM) \
diff --git a/lib/sbi/server.c b/lib/sbi/server.c
index f0c1e207e..e0bc83e8c 100644
--- a/lib/sbi/server.c
+++ b/lib/sbi/server.c
@@ -75,6 +75,8 @@ ogs_sbi_server_t *ogs_sbi_server_add(
ogs_strdup(ogs_sbi_self()->tls.server.private_key);
if (ogs_sbi_self()->tls.server.cert)
server->cert = ogs_strdup(ogs_sbi_self()->tls.server.cert);
+ if (ogs_sbi_self()->tls.server.sslkeylog)
+ server->sslkeylog = ogs_strdup(ogs_sbi_self()->tls.server.sslkeylog);
server->verify_client = ogs_sbi_self()->tls.server.verify_client;
if (ogs_sbi_self()->tls.server.verify_client_cacert)
@@ -112,6 +114,8 @@ void ogs_sbi_server_remove(ogs_sbi_server_t *server)
ogs_free(server->private_key);
if (server->cert)
ogs_free(server->cert);
+ if (server->sslkeylog)
+ ogs_free(server->sslkeylog);
ogs_pool_id_free(&server_pool, server);
}
diff --git a/lib/sbi/server.h b/lib/sbi/server.h
index af58a0cf1..19db7d806 100644
--- a/lib/sbi/server.h
+++ b/lib/sbi/server.h
@@ -41,7 +41,7 @@ typedef struct ogs_sbi_server_s {
char *interface;
OpenAPI_uri_scheme_e scheme;
- char *private_key, *cert;
+ char *private_key, *cert, *sslkeylog;
bool verify_client;
char *verify_client_cacert;
diff --git a/lib/sctp/ogs-lksctp.c b/lib/sctp/ogs-lksctp.c
index 89a6b985c..c40a99136 100644
--- a/lib/sctp/ogs-lksctp.c
+++ b/lib/sctp/ogs-lksctp.c
@@ -53,138 +53,367 @@ ogs_sock_t *ogs_sctp_socket(int family, int type)
return new;
}
-ogs_sock_t *ogs_sctp_server(
- int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
+/**
+ * Determines the appropriate SCTP socket family based on the provided
+ * address list.
+ * Returns AF_INET6 if any address in sa_list is IPv6, otherwise AF_INET.
+ * Returns AF_UNSPEC if sa_list is NULL or no suitable family is found.
+ *
+ * @param sa_list List of addresses to check.
+ * @return AF_INET6, AF_INET, or AF_UNSPEC if no suitable family is found.
+ */
+static int sctp_socket_family_from_addr_list(const ogs_sockaddr_t *sa_list)
{
- int rv;
- char buf[OGS_ADDRSTRLEN];
+ const ogs_sockaddr_t *addr = sa_list;
- ogs_sock_t *new = NULL;
- ogs_sockaddr_t *addr;
- ogs_sockopt_t option;
+ if (!sa_list) {
+ ogs_error("Address list is NULL");
+ return AF_UNSPEC;
+ }
- ogs_assert(sa_list);
-
- ogs_sockopt_init(&option);
- if (socket_option)
- memcpy(&option, socket_option, sizeof option);
-
- addr = sa_list;
- while (addr) {
- new = ogs_sctp_socket(addr->ogs_sa_family, type);
- if (new) {
- rv = ogs_sctp_peer_addr_params(new, &option);
- ogs_assert(rv == OGS_OK);
-
- rv = ogs_sctp_rto_info(new, &option);
- ogs_assert(rv == OGS_OK);
-
- rv = ogs_sctp_initmsg(new, &option);
- ogs_assert(rv == OGS_OK);
-
- if (option.sctp_nodelay == true) {
- rv = ogs_sctp_nodelay(new, true);
- ogs_assert(rv == OGS_OK);
- } else
- ogs_warn("SCTP NO_DELAY Disabled");
-
- if (option.so_linger.l_onoff == true) {
- rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
- ogs_assert(rv == OGS_OK);
- }
-
- rv = ogs_listen_reusable(new->fd, true);
- ogs_assert(rv == OGS_OK);
-
- if (ogs_sock_bind(new, addr) == OGS_OK) {
- ogs_debug("sctp_server() [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
- break;
- }
-
- ogs_sock_destroy(new);
+ /* Iterate through the address list to find an IPv6 address */
+ while (addr != NULL) {
+ if (addr->ogs_sa_family == AF_INET6) {
+ return AF_INET6;
}
-
addr = addr->next;
}
- if (addr == NULL) {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "sctp_server() [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ /* Default to AF_INET if no IPv6 address is found */
+ return AF_INET;
+}
+
+
+/**
+ * @brief
+ * 1) Count the number of addresses in sa_list and determine the total
+ * buffer size.
+ * 2) Allocate a single continuous buffer (unsigned char).
+ * 3) Copy each address (sockaddr_in or sockaddr_in6) into this continuous
+ * buffer.
+ *
+ * @param sa_list Linked list of ogs_sockaddr_t structures.
+ * @param out_count [OUT] Receives the number of addresses.
+ * @param out_total_len [OUT] Receives the total bytes for the continuous
+ * buffer.
+ *
+ * @return
+ * On success, returns a pointer to the allocated buffer containing all
+ * addresses. On failure, logs an error and returns NULL.
+ */
+static unsigned char *create_continuous_address_buffer(
+ ogs_sockaddr_t *sa_list,
+ int *out_count,
+ int *out_total_len)
+{
+ ogs_sockaddr_t *addr;
+ int addr_count = 0;
+ int total_len = 0;
+ unsigned char *addr_buf = NULL;
+ int offset = 0;
+
+ /* 1) Count addresses and total buffer size needed. */
+ for (addr = sa_list; addr; addr = addr->next) {
+ addr_count++;
+ /* E.g., sizeof(sockaddr_in) or sizeof(sockaddr_in6). */
+ total_len += ogs_sockaddr_len(addr);
+ }
+
+ if (addr_count == 0) {
+ ogs_error("No valid address in sa_list");
return NULL;
}
- ogs_assert(new);
+ /* 2) Allocate the continuous buffer (unsigned char). */
+ addr_buf = ogs_calloc(1, total_len);
+ if (!addr_buf) {
+ ogs_error("Failed to allocate memory for addr_buf");
+ return NULL;
+ }
- rv = ogs_sock_listen(new);
+ /* 3) Copy each address structure into addr_buf. */
+ offset = 0;
+ for (addr = sa_list; addr; addr = addr->next) {
+ socklen_t socklen = ogs_sockaddr_len(addr);
+ memcpy(addr_buf + offset, &addr->sa, socklen);
+ offset += socklen;
+ }
+
+ /* Pass back the number of addresses and total length. */
+ *out_count = addr_count;
+ *out_total_len = total_len;
+
+ return addr_buf;
+}
+
+/**
+ * @brief Create an SCTP server socket and bind multiple addresses at once
+ * using sctp_bindx().
+ *
+ * @param type SCTP socket type (e.g., SOCK_SEQPACKET or SOCK_STREAM)
+ * @param sa_list Linked list of ogs_sockaddr_t structures
+ * @param socket_option Additional socket/SCTP options
+ *
+ * @return
+ * On success, returns a pointer to an ogs_sock_t instance; on failure,
+ * returns NULL.
+ */
+ogs_sock_t *ogs_sctp_server(
+ int type,
+ ogs_sockaddr_t *sa_list,
+ ogs_sockopt_t *socket_option)
+{
+ int rv;
+ int sa_family;
+ ogs_sock_t *new_sock = NULL;
+ ogs_sockopt_t option;
+
+ /* Variables for sctp_bindx() usage. */
+ unsigned char *addr_buf = NULL;
+ int addr_count = 0;
+ int total_len = 0;
+
+ ogs_assert(sa_list);
+
+ /* Initialize socket options. */
+ ogs_sockopt_init(&option);
+ if (socket_option)
+ memcpy(&option, socket_option, sizeof(option));
+
+ /*
+ * Obtain a contiguous buffer for all addresses:
+ * 1) Count the addresses.
+ * 2) Allocate the buffer.
+ * 3) Copy the addresses into the buffer.
+ */
+ addr_buf = create_continuous_address_buffer(
+ sa_list, &addr_count, &total_len);
+ if (!addr_buf) {
+ /* The helper logs errors, so just return. */
+ ogs_error("create_continuous_address_buffer() failed");
+ goto err;
+ }
+
+ /* Determine the appropriate address family from sa_list */
+ sa_family = sctp_socket_family_from_addr_list(sa_list);
+ if (sa_family == AF_UNSPEC) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_client() No suitable address family found "
+ "in sa_list");
+ goto err;
+ }
+
+ /* Create the SCTP socket using the determined address family */
+ new_sock = ogs_sctp_socket(sa_family, type);
+
+ /* Configure SCTP-specific options. */
+ rv = ogs_sctp_peer_addr_params(new_sock, &option);
ogs_assert(rv == OGS_OK);
- return new;
+ rv = ogs_sctp_rto_info(new_sock, &option);
+ ogs_assert(rv == OGS_OK);
+
+ rv = ogs_sctp_initmsg(new_sock, &option);
+ ogs_assert(rv == OGS_OK);
+
+ if (option.sctp_nodelay == true) {
+ rv = ogs_sctp_nodelay(new_sock, true);
+ ogs_assert(rv == OGS_OK);
+ } else {
+ ogs_warn("SCTP NO_DELAY Disabled");
+ }
+
+ if (option.so_linger.l_onoff == true) {
+ rv = ogs_sctp_so_linger(new_sock, option.so_linger.l_linger);
+ ogs_assert(rv == OGS_OK);
+ }
+
+ /* Enable address reuse if needed. */
+ rv = ogs_listen_reusable(new_sock->fd, true);
+ ogs_assert(rv == OGS_OK);
+
+ /*
+ * Bind all addresses at once using sctp_bindx().
+ * (struct sockaddr *)addr_buf points to the contiguous buffer.
+ */
+ rv = sctp_bindx(new_sock->fd, (struct sockaddr *)addr_buf,
+ addr_count, SCTP_BINDX_ADD_ADDR);
+ if (rv < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_bindx() failed to bind multiple addresses");
+ goto err;
+ }
+
+ /*
+ * Log debug info: only the first address is shown here as an example.
+ */
+ ogs_debug("sctp_server() %s (bound %d addresses)",
+ ogs_sockaddr_to_string_static(sa_list), addr_count);
+
+ /* Start listening for connections. */
+ rv = ogs_sock_listen(new_sock);
+ ogs_assert(rv == OGS_OK);
+
+ /* Success: free the buffer and return the socket. */
+ ogs_free(addr_buf);
+ return new_sock;
+
+err:
+ if (addr_buf)
+ ogs_free(addr_buf);
+ if (new_sock)
+ ogs_sock_destroy(new_sock);
+
+ /*
+ * On failure, log an error based on the first address
+ * in sa_list (customize as needed).
+ */
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_server() %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
+
+ return NULL;
}
ogs_sock_t *ogs_sctp_client(
- int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
+ int type,
+ ogs_sockaddr_t *sa_list,
+ ogs_sockaddr_t *local_sa_list,
+ ogs_sockopt_t *socket_option)
{
int rv;
- char buf[OGS_ADDRSTRLEN];
-
- ogs_sock_t *new = NULL;
- ogs_sockaddr_t *addr;
+ int sa_family;
+ ogs_sock_t *new_sock = NULL;
ogs_sockopt_t option;
+ /* Buffers and counters for remote addresses. */
+ unsigned char *remote_buf = NULL;
+ int remote_count = 0;
+ int remote_len = 0;
+
+ /* Buffers and counters for local addresses (if provided). */
+ unsigned char *local_buf = NULL;
+ int local_count = 0;
+ int local_len = 0;
+
ogs_assert(sa_list);
+ /* Initialize socket options and copy user-provided options if present. */
ogs_sockopt_init(&option);
if (socket_option)
- memcpy(&option, socket_option, sizeof option);
+ memcpy(&option, socket_option, sizeof(option));
- addr = sa_list;
- while (addr) {
- new = ogs_sctp_socket(addr->ogs_sa_family, type);
- if (new) {
- rv = ogs_sctp_peer_addr_params(new, &option);
- ogs_assert(rv == OGS_OK);
-
- rv = ogs_sctp_rto_info(new, &option);
- ogs_assert(rv == OGS_OK);
-
- rv = ogs_sctp_initmsg(new, &option);
- ogs_assert(rv == OGS_OK);
-
- if (option.sctp_nodelay == true) {
- rv = ogs_sctp_nodelay(new, true);
- ogs_assert(rv == OGS_OK);
- } else
- ogs_warn("SCTP NO_DELAY Disabled");
-
- if (option.so_linger.l_onoff == true) {
- rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
- ogs_assert(rv == OGS_OK);
- }
-
- if (ogs_sock_connect(new, addr) == OGS_OK) {
- ogs_debug("sctp_client() [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
- break;
- }
-
- ogs_sock_destroy(new);
- }
-
- addr = addr->next;
+ /*
+ * Build the contiguous buffer for REMOTE addresses using our helper
+ * function. This will be used later by sctp_connectx().
+ */
+ remote_buf = create_continuous_address_buffer(
+ sa_list, &remote_count, &remote_len);
+ if (!remote_buf) {
+ ogs_error("create_continuous_address_buffer() failed");
+ goto err;
}
- if (addr == NULL) {
+ /* Determine the appropriate address family from sa_list */
+ sa_family = sctp_socket_family_from_addr_list(sa_list);
+ if (sa_family == AF_UNSPEC) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "sctp_client() [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
- return NULL;
+ "sctp_client() No suitable address family found "
+ "in sa_list");
+ goto err;
}
- ogs_assert(new);
+ /* Create the SCTP socket using the determined address family */
+ new_sock = ogs_sctp_socket(sa_family, type);
- return new;
+ /* Configure SCTP-specific options. */
+ rv = ogs_sctp_peer_addr_params(new_sock, &option);
+ ogs_assert(rv == OGS_OK);
+
+ rv = ogs_sctp_rto_info(new_sock, &option);
+ ogs_assert(rv == OGS_OK);
+
+ rv = ogs_sctp_initmsg(new_sock, &option);
+ ogs_assert(rv == OGS_OK);
+
+ if (option.sctp_nodelay == true) {
+ rv = ogs_sctp_nodelay(new_sock, true);
+ ogs_assert(rv == OGS_OK);
+ } else {
+ ogs_warn("SCTP NO_DELAY Disabled");
+ }
+
+ if (option.so_linger.l_onoff == true) {
+ rv = ogs_sctp_so_linger(new_sock, option.so_linger.l_linger);
+ ogs_assert(rv == OGS_OK);
+ }
+
+ /*
+ * If local_sa_list is provided, bind those addresses before connecting.
+ * (Optional: some clients do not need explicit local bind.)
+ */
+ if (local_sa_list) {
+ local_buf = create_continuous_address_buffer(
+ local_sa_list, &local_count, &local_len);
+ if (!local_buf) {
+ /* Error already logged. */
+ goto err;
+ }
+ /* We can bind them using sctp_bindx() if desired. */
+ rv = sctp_bindx(new_sock->fd,
+ (struct sockaddr *)local_buf,
+ local_count,
+ SCTP_BINDX_ADD_ADDR);
+ if (rv < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_client() bind local addresses failed");
+ goto err;
+ }
+ ogs_debug("sctp_client() bound %d local addresses", local_count);
+ }
+
+ /*
+ * Connect to the REMOTE addresses using sctp_connectx().
+ * (struct sockaddr *)remote_buf is the contiguous buffer.
+ */
+ rv = sctp_connectx(new_sock->fd,
+ (struct sockaddr *)remote_buf,
+ remote_count,
+ NULL /* assoc_id */);
+ if (rv < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_connectx() failed to connect");
+ goto err;
+ }
+
+ /* Debug log for the first remote address. */
+ ogs_debug("sctp_client() connected to %s",
+ ogs_sockaddr_to_string_static(sa_list));
+
+ /* Success: free buffers and return the new socket. */
+ if (local_buf)
+ ogs_free(local_buf);
+ if (remote_buf)
+ ogs_free(remote_buf);
+ return new_sock;
+
+err:
+ if (local_buf)
+ ogs_free(local_buf);
+ if (remote_buf)
+ ogs_free(remote_buf);
+ if (new_sock)
+ ogs_sock_destroy(new_sock);
+
+ /*
+ * On failure, log an error based on the first remote address.
+ * Adjust to your needs, e.g., log local too if necessary.
+ */
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "sctp_client() %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
+
+ return NULL;
}
int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
@@ -211,8 +440,9 @@ int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "sctp_connect() [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ "sctp_connect() %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
+
return OGS_ERROR;
}
diff --git a/lib/sctp/ogs-sctp.h b/lib/sctp/ogs-sctp.h
index 3384a98df..f698bf6af 100644
--- a/lib/sctp/ogs-sctp.h
+++ b/lib/sctp/ogs-sctp.h
@@ -109,7 +109,9 @@ ogs_sock_t *ogs_sctp_socket(int family, int type);
ogs_sock_t *ogs_sctp_server(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_sctp_client(
- int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
+ int type,
+ ogs_sockaddr_t *sa_list, ogs_sockaddr_t *local_sa_list,
+ ogs_sockopt_t *socket_option);
int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
diff --git a/lib/sctp/ogs-usrsctp.c b/lib/sctp/ogs-usrsctp.c
index 60675ca93..a587fbcae 100644
--- a/lib/sctp/ogs-usrsctp.c
+++ b/lib/sctp/ogs-usrsctp.c
@@ -142,8 +142,8 @@ ogs_sock_t *ogs_sctp_server(
}
if (addr == NULL) {
- ogs_error("sctp_server [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_error("sctp_server %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
return NULL;
}
@@ -156,7 +156,9 @@ ogs_sock_t *ogs_sctp_server(
}
ogs_sock_t *ogs_sctp_client(
- int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
+ int type,
+ ogs_sockaddr_t *sa_list, ogs_sockaddr_t *local_sa_list,
+ ogs_sockopt_t *socket_option)
{
int rv;
char buf[OGS_ADDRSTRLEN];
@@ -208,8 +210,8 @@ ogs_sock_t *ogs_sctp_client(
}
if (addr == NULL) {
- ogs_error("sctp_client [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_error("sctp_client %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
return NULL;
}
@@ -219,7 +221,6 @@ ogs_sock_t *ogs_sctp_client(
int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
{
struct socket *socket = (struct socket *)sock;
- char buf[OGS_ADDRSTRLEN];
socklen_t addrlen;
ogs_assert(socket);
@@ -229,13 +230,13 @@ int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
ogs_assert(addrlen);
if (usrsctp_bind(socket, &sa_list->sa, addrlen) != 0) {
- ogs_error("sctp_bind() [%s]:%d failed",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_error("sctp_bind() %s failed",
+ ogs_sockaddr_to_string_static(sa_list));
+
return OGS_ERROR;
}
- ogs_debug("sctp_bind() [%s]:%d",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_debug("sctp_bind() %s", ogs_sockaddr_to_string_static(sa_list));
return OGS_OK;
}
@@ -243,7 +244,6 @@ int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
{
struct socket *socket = (struct socket *)sock;
- char buf[OGS_ADDRSTRLEN];
socklen_t addrlen;
ogs_assert(socket);
@@ -253,13 +253,11 @@ int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
ogs_assert(addrlen);
if (usrsctp_connect(socket, &sa_list->sa, addrlen) != 0) {
- ogs_error("sctp_connect() [%s]:%d",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_error("sctp_connect() %s", ogs_sockaddr_to_string_static(sa_list));
return OGS_ERROR;
}
- ogs_debug("sctp_connect() [%s]:%d",
- OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
+ ogs_debug("sctp_connect() %s", ogs_sockaddr_to_string_static(sa_list));
return OGS_OK;
}
diff --git a/meson.build b/meson.build
index b3befad2b..c54a57768 100644
--- a/meson.build
+++ b/meson.build
@@ -57,7 +57,7 @@ if clangtidy.found() != true
endif
meson.add_install_script(python3_exe, '-c',
- mkdir_p.format(join_paths(localstatedir, 'log', 'open5gs')))
+ mkdir_p.format(join_paths(localstatedir, 'log', 'open5gs', 'tls')))
# Compiler flags
if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c
index 49a9a6f66..652f711da 100644
--- a/src/amf/amf-sm.c
+++ b/src/amf/amf-sm.c
@@ -845,6 +845,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
if (!gnb) {
ogs_error("amf_gnb_add() failed");
ogs_free(addr);
+ break;
}
} else {
ogs_free(addr);
diff --git a/src/amf/context.c b/src/amf/context.c
index 10204f7d1..676db8e17 100644
--- a/src/amf/context.c
+++ b/src/amf/context.c
@@ -1258,7 +1258,8 @@ void amf_gnb_remove(amf_gnb_t *gnb)
ogs_hash_set(self.gnb_addr_hash,
gnb->sctp.addr, sizeof(ogs_sockaddr_t), NULL);
- ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL);
+ if (gnb->gnb_id_presence == true)
+ ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL);
ogs_sctp_flush_and_destroy(&gnb->sctp);
@@ -1294,11 +1295,14 @@ int amf_gnb_set_gnb_id(amf_gnb_t *gnb, uint32_t gnb_id)
{
ogs_assert(gnb);
- ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL);
+ if (gnb->gnb_id_presence == true)
+ ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), NULL);
gnb->gnb_id = gnb_id;
ogs_hash_set(self.gnb_id_hash, &gnb->gnb_id, sizeof(gnb->gnb_id), gnb);
+ gnb->gnb_id_presence = true;
+
return OGS_OK;
}
@@ -2261,6 +2265,7 @@ amf_sess_t *amf_sess_add(amf_ue_t *amf_ue, uint8_t psi)
sess->s_nssai.sst = 0;
sess->s_nssai.sd.v = OGS_S_NSSAI_NO_SD_VALUE;
+ sess->mapped_hplmn_presence = false;
sess->mapped_hplmn.sst = 0;
sess->mapped_hplmn.sd.v = OGS_S_NSSAI_NO_SD_VALUE;
@@ -2863,6 +2868,8 @@ bool amf_update_allowed_nssai(amf_ue_t *amf_ue)
allowed->sst = requested->sst;
allowed->sd.v = requested->sd.v;
+ allowed->mapped_hplmn_sst_presence =
+ requested->mapped_hplmn_sst_presence;
allowed->mapped_hplmn_sst = requested->mapped_hplmn_sst;
allowed->mapped_hplmn_sd.v = requested->mapped_hplmn_sd.v;
@@ -2899,6 +2906,7 @@ bool amf_update_allowed_nssai(amf_ue_t *amf_ue)
allowed->sst = slice->s_nssai.sst;
allowed->sd.v = slice->s_nssai.sd.v;
+ allowed->mapped_hplmn_sst_presence = false;
allowed->mapped_hplmn_sst = 0;
allowed->mapped_hplmn_sd.v = OGS_S_NSSAI_NO_SD_VALUE;
diff --git a/src/amf/context.h b/src/amf/context.h
index 7d188aa1e..d849ee7de 100644
--- a/src/amf/context.h
+++ b/src/amf/context.h
@@ -139,6 +139,7 @@ typedef struct amf_gnb_s {
ogs_fsm_t sm; /* A state machine */
+ bool gnb_id_presence;
uint32_t gnb_id; /* gNB_ID received from gNB */
ogs_plmn_id_t plmn_id; /* gNB PLMN-ID received from gNB */
ogs_sctp_sock_t sctp; /* SCTP socket */
@@ -835,6 +836,7 @@ typedef struct amf_sess_s {
ogs_s_nssai_t s_nssai;
ogs_s_nssai_t mapped_hplmn;
+ bool mapped_hplmn_presence;
char *dnn;
bool lbo_roaming_allowed;
diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c
index 4474234b0..c3e87d8c0 100644
--- a/src/amf/gmm-handler.c
+++ b/src/amf/gmm-handler.c
@@ -1290,6 +1290,12 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
if (ie.sst == amf_ue->slice[i].s_nssai.sst &&
ie.sd.v == amf_ue->slice[i].s_nssai.sd.v) {
+ if (ie.mapped_hplmn_sst_presence) {
+ sess->mapped_hplmn_presence = true;
+ sess->mapped_hplmn.sst = ie.mapped_hplmn_sst;
+ sess->mapped_hplmn.sd.v = ie.mapped_hplmn_sd.v;
+ }
+
/* PASS */
} else {
diff --git a/src/amf/gmm-sm.c b/src/amf/gmm-sm.c
index f17cae690..123a779e4 100644
--- a/src/amf/gmm-sm.c
+++ b/src/amf/gmm-sm.c
@@ -547,61 +547,64 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
SWITCH(sbi_message->h.resource.component[2])
- CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
+ CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
- r = OGS_ERROR;
-
- if (sbi_message->res_status == OGS_SBI_HTTP_STATUS_OK) {
- amf_ue->amf_ue_context_transfer_state = UE_CONTEXT_TRANSFER_NEW_AMF_STATE;
- r = amf_namf_comm_handle_ue_context_transfer_response(
- sbi_message, amf_ue);
- if (r != OGS_OK) {
- ogs_error("failed to handle "
- "UE_CONTEXT_TRANSFER response");
- amf_ue->amf_ue_context_transfer_state = UE_CONTEXT_INITIAL_STATE;
- }
- } else {
- ogs_error("[%s] HTTP response error [%d]",
- amf_ue->suci, sbi_message->res_status);
- amf_ue->amf_ue_context_transfer_state = UE_CONTEXT_INITIAL_STATE;
- }
+ r = OGS_ERROR;
+ if (sbi_message->res_status == OGS_SBI_HTTP_STATUS_OK) {
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_TRANSFER_NEW_AMF_STATE;
+ r = amf_namf_comm_handle_ue_context_transfer_response(
+ sbi_message, amf_ue);
if (r != OGS_OK) {
- if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
- AMF_UE_HAVE_SUPI(amf_ue))) {
- CLEAR_AMF_UE_TIMER(amf_ue->t3570);
- r = nas_5gs_send_identity_request(amf_ue);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- break;
- }
+ ogs_error("failed to handle "
+ "UE_CONTEXT_TRANSFER response");
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_INITIAL_STATE;
}
+ } else {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_INITIAL_STATE;
+ }
- xact_count = amf_sess_xact_count(amf_ue);
- amf_sbi_send_release_all_sessions(
- ran_ue_find_by_id(amf_ue->ran_ue_id), amf_ue,
- AMF_RELEASE_SM_CONTEXT_NO_STATE);
-
- if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
- amf_sess_xact_count(amf_ue) == xact_count) {
- r = amf_ue_sbi_discover_and_send(
- OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
- amf_nausf_auth_build_authenticate,
- amf_ue, 0, NULL);
+ if (r != OGS_OK) {
+ if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
+ AMF_UE_HAVE_SUPI(amf_ue))) {
+ CLEAR_AMF_UE_TIMER(amf_ue->t3570);
+ r = nas_5gs_send_identity_request(amf_ue);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
+ break;
}
+ }
- OGS_FSM_TRAN(s, &gmm_state_authentication);
- break;
+ xact_count = amf_sess_xact_count(amf_ue);
+ amf_sbi_send_release_all_sessions(
+ ran_ue_find_by_id(amf_ue->ran_ue_id), amf_ue,
+ AMF_RELEASE_SM_CONTEXT_NO_STATE);
- DEFAULT
- ogs_error("Invalid resource name [%s]",
- sbi_message->h.resource.component[2]);
- ogs_assert_if_reached();
- END
+ if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
+ amf_sess_xact_count(amf_ue) == xact_count) {
+ r = amf_ue_sbi_discover_and_send(
+ OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
+ amf_nausf_auth_build_authenticate,
+ amf_ue, 0, NULL);
+ ogs_expect(r == OGS_OK);
+ ogs_assert(r != OGS_ERROR);
+ }
+
+ OGS_FSM_TRAN(s, &gmm_state_authentication);
break;
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]);
+ ogs_assert_if_reached();
+ END
+ break;
+
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message->h.resource.component[0]);
@@ -1173,6 +1176,75 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
END
break;
+ CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
+ SWITCH(sbi_message->h.resource.component[2])
+ CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
+
+ r = OGS_ERROR;
+
+ if (sbi_message->res_status == OGS_SBI_HTTP_STATUS_OK) {
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_TRANSFER_NEW_AMF_STATE;
+ r = amf_namf_comm_handle_ue_context_transfer_response(
+ sbi_message, amf_ue);
+ if (r != OGS_OK) {
+ ogs_error("failed to handle "
+ "UE_CONTEXT_TRANSFER response");
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_INITIAL_STATE;
+ }
+ } else {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ amf_ue->amf_ue_context_transfer_state =
+ UE_CONTEXT_INITIAL_STATE;
+ }
+
+ if (r != OGS_OK) {
+ if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
+ AMF_UE_HAVE_SUPI(amf_ue))) {
+ CLEAR_AMF_UE_TIMER(amf_ue->t3570);
+ r = nas_5gs_send_identity_request(amf_ue);
+ ogs_expect(r == OGS_OK);
+ ogs_assert(r != OGS_ERROR);
+ break;
+ }
+ }
+
+ xact_count = amf_sess_xact_count(amf_ue);
+ amf_sbi_send_release_all_sessions(
+ ran_ue_find_by_id(amf_ue->ran_ue_id), amf_ue,
+ AMF_RELEASE_SM_CONTEXT_NO_STATE);
+
+ if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
+ amf_sess_xact_count(amf_ue) == xact_count) {
+ r = amf_ue_sbi_discover_and_send(
+ OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
+ amf_nausf_auth_build_authenticate,
+ amf_ue, 0, NULL);
+ ogs_expect(r == OGS_OK);
+ ogs_assert(r != OGS_ERROR);
+ }
+
+ OGS_FSM_TRAN(s, &gmm_state_authentication);
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[2]);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
DEFAULT
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
ogs_assert_if_reached();
@@ -1905,6 +1977,31 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
END
break;
+ CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_POLICIES)
+ SWITCH(sbi_message->h.method)
+ CASE(OGS_SBI_HTTP_METHOD_POST)
+ if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_CREATED) {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->supi, sbi_message->res_status);
+ }
+ ogs_error("[%s] Ignore SBI message", amf_ue->supi);
+ break;
+
+ DEFAULT
+ ogs_error("Unknown method [%s]", sbi_message->h.method);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
DEFAULT
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
ogs_assert_if_reached();
@@ -2123,6 +2220,53 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(sbi_message);
SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_UE_AUTHENTICATIONS)
+
+ if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_CREATED &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT) {
+ if (sbi_message->res_status ==
+ OGS_SBI_HTTP_STATUS_NOT_FOUND) {
+ ogs_warn("[%s] Cannot find SUCI [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ } else {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ }
+ }
+
+ SWITCH(sbi_message->h.method)
+ CASE(OGS_SBI_HTTP_METHOD_POST)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_PUT)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_DELETE)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ DEFAULT
+ ogs_error("[%s] Invalid HTTP method [%s]",
+ amf_ue->suci, sbi_message->h.method);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA)
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA_CONFIRMATION)
+ CASE(OGS_SBI_RESOURCE_NAME_EAP_SESSION)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->supi);
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
@@ -2257,6 +2401,53 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
state = e->h.sbi.state;
SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_UE_AUTHENTICATIONS)
+
+ if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_CREATED &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT) {
+ if (sbi_message->res_status ==
+ OGS_SBI_HTTP_STATUS_NOT_FOUND) {
+ ogs_warn("[%s] Cannot find SUCI [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ } else {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ }
+ }
+
+ SWITCH(sbi_message->h.method)
+ CASE(OGS_SBI_HTTP_METHOD_POST)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_PUT)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_DELETE)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ DEFAULT
+ ogs_error("[%s] Invalid HTTP method [%s]",
+ amf_ue->suci, sbi_message->h.method);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA)
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA_CONFIRMATION)
+ CASE(OGS_SBI_RESOURCE_NAME_EAP_SESSION)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->supi);
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
SWITCH(sbi_message->h.resource.component[1])
@@ -2815,6 +3006,53 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(ran_ue);
SWITCH(sbi_message->h.service.name)
+ CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)
+ SWITCH(sbi_message->h.resource.component[0])
+ CASE(OGS_SBI_RESOURCE_NAME_UE_AUTHENTICATIONS)
+
+ if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_CREATED &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK &&
+ sbi_message->res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT) {
+ if (sbi_message->res_status ==
+ OGS_SBI_HTTP_STATUS_NOT_FOUND) {
+ ogs_warn("[%s] Cannot find SUCI [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ } else {
+ ogs_error("[%s] HTTP response error [%d]",
+ amf_ue->suci, sbi_message->res_status);
+ }
+ }
+
+ SWITCH(sbi_message->h.method)
+ CASE(OGS_SBI_HTTP_METHOD_POST)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_PUT)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ CASE(OGS_SBI_HTTP_METHOD_DELETE)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->suci);
+ break;
+ DEFAULT
+ ogs_error("[%s] Invalid HTTP method [%s]",
+ amf_ue->suci, sbi_message->h.method);
+ ogs_assert_if_reached();
+ END
+ break;
+
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA)
+ CASE(OGS_SBI_RESOURCE_NAME_5G_AKA_CONFIRMATION)
+ CASE(OGS_SBI_RESOURCE_NAME_EAP_SESSION)
+ ogs_warn("[%s] Ignore SBI message", amf_ue->supi);
+ break;
+
+ DEFAULT
+ ogs_error("Invalid resource name [%s]",
+ sbi_message->h.resource.component[0]);
+ ogs_assert_if_reached();
+ END
+ break;
+
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c
index 15b350c52..bbb316bf6 100644
--- a/src/amf/ngap-handler.c
+++ b/src/amf/ngap-handler.c
@@ -38,14 +38,16 @@ static bool maximum_number_of_gnbs_is_reached(void)
static bool gnb_plmn_id_is_foreign(amf_gnb_t *gnb)
{
- int i, j;
-
- for (i = 0; i < gnb->num_of_supported_ta_list; i++) {
- for (j = 0; j < gnb->supported_ta_list[i].num_of_bplmn_list; j++) {
- if (memcmp(&gnb->plmn_id,
- &gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
- OGS_PLMN_ID_LEN) == 0)
- return false;
+ int i, j, k;
+ for (i = 0; i < amf_self()->num_of_plmn_support; i++) {
+ for (j = 0; j < gnb->num_of_supported_ta_list; j++) {
+ for (k = 0; k < gnb->supported_ta_list[j].num_of_bplmn_list; k++) {
+ if (memcmp(&amf_self()->plmn_support[i].plmn_id,
+ &gnb->supported_ta_list[j].bplmn_list[k].plmn_id,
+ OGS_PLMN_ID_LEN) == 0){
+ return false;
+ }
+ }
}
}
diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c
index 47b221b36..8e284787f 100644
--- a/src/amf/ngap-path.c
+++ b/src/amf/ngap-path.c
@@ -168,6 +168,12 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
ogs_assert(ran_ue);
ogs_assert(nasPdu);
+ if (nasPdu->size == 0) {
+ ogs_error("Empty NAS PDU");
+ ran_ue_remove(ran_ue);
+ return OGS_ERROR;
+ }
+
amf_ue = amf_ue_find_by_id(ran_ue->amf_ue_id);
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
diff --git a/src/amf/nsmf-build.c b/src/amf/nsmf-build.c
index 78cda7e65..f7cf9c44f 100644
--- a/src/amf/nsmf-build.c
+++ b/src/amf/nsmf-build.c
@@ -117,7 +117,7 @@ ogs_sbi_request_t *amf_nsmf_pdusession_build_create_sm_context(
sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
SmContextCreateData.s_nssai = &sNssai;
- if (sess->mapped_hplmn.sst) {
+ if (sess->mapped_hplmn_presence) {
hplmnSnssai.sst = sess->mapped_hplmn.sst;
hplmnSnssai.sd = ogs_s_nssai_sd_to_string(sess->mapped_hplmn.sd);
SmContextCreateData.hplmn_snssai = &hplmnSnssai;
diff --git a/src/mme/emm-build.c b/src/mme/emm-build.c
index 4eba1d233..e9cc8e187 100644
--- a/src/mme/emm-build.c
+++ b/src/mme/emm-build.c
@@ -83,6 +83,11 @@ ogs_pkbuf_t *emm_build_attach_accept(
if (mme_ue->network_access_mode == OGS_NETWORK_ACCESS_MODE_ONLY_PACKET) {
/* permit only EPS_ATTACH */
eps_attach_result->result = OGS_NAS_ATTACH_TYPE_EPS_ATTACH;
+ if (ogs_global_conf()->parameter.fake_csfb == true)
+ eps_attach_result->result =
+ OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH;
+ else
+ eps_attach_result->result = OGS_NAS_ATTACH_TYPE_EPS_ATTACH;
} else {
eps_attach_result->result = mme_ue->nas_eps.attach.value;
}
diff --git a/src/mme/emm-sm.c b/src/mme/emm-sm.c
index e1045f166..38f817ddf 100644
--- a/src/mme/emm-sm.c
+++ b/src/mme/emm-sm.c
@@ -667,7 +667,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
} else {
if (e->s1ap_code == S1AP_ProcedureCode_id_initialUEMessage) {
- ogs_debug(" Iniital UE Message");
+ ogs_debug(" Initial UE Message");
if (mme_ue->nas_eps.update.active_flag) {
/*
diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c
index 6f1d412f9..426ea274a 100644
--- a/src/mme/mme-context.c
+++ b/src/mme/mme-context.c
@@ -2050,9 +2050,9 @@ int mme_context_parse_config(void)
while (ogs_yaml_iter_next(&sgsap_iter)) {
const char *sgsap_key = ogs_yaml_iter_key(&sgsap_iter);
ogs_assert(sgsap_key);
- if (!strcmp(sgsap_key, "server")) {
- ogs_yaml_iter_t server_iter, server_array;
- ogs_yaml_iter_recurse(&sgsap_iter, &server_array);
+ if (!strcmp(sgsap_key, "client")) {
+ ogs_yaml_iter_t client_iter, client_array;
+ ogs_yaml_iter_recurse(&sgsap_iter, &client_array);
do {
mme_vlr_t *vlr = NULL;
ogs_plmn_id_t plmn_id;
@@ -2063,38 +2063,39 @@ int mme_context_parse_config(void)
const char *tac, *lac;
} map[MAX_NUM_OF_CSMAP];
int map_num = 0;
- ogs_sockaddr_t *addr = NULL;
+ ogs_sockaddr_t *addr = NULL, *local_addr = NULL;
int family = AF_UNSPEC;
- int i, hostname_num = 0;
- const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
+ int i, hostname_num = 0, local_hostname_num = 0;
+ const char *hostname[OGS_MAX_NUM_OF_HOSTNAME],
+ *local_hostname[OGS_MAX_NUM_OF_HOSTNAME];
uint16_t port = self.sgsap_port;
ogs_sockopt_t option;
bool is_option = false;
- if (ogs_yaml_iter_type(&server_array) ==
+ if (ogs_yaml_iter_type(&client_array) ==
YAML_MAPPING_NODE) {
- memcpy(&server_iter, &server_array,
+ memcpy(&client_iter, &client_array,
sizeof(ogs_yaml_iter_t));
- } else if (ogs_yaml_iter_type(&server_array) ==
+ } else if (ogs_yaml_iter_type(&client_array) ==
YAML_SEQUENCE_NODE) {
- if (!ogs_yaml_iter_next(&server_array))
+ if (!ogs_yaml_iter_next(&client_array))
break;
ogs_yaml_iter_recurse(
- &server_array, &server_iter);
- } else if (ogs_yaml_iter_type(&server_array) ==
+ &client_array, &client_iter);
+ } else if (ogs_yaml_iter_type(&client_array) ==
YAML_SCALAR_NODE) {
break;
} else
ogs_assert_if_reached();
- while (ogs_yaml_iter_next(&server_iter)) {
- const char *server_key =
- ogs_yaml_iter_key(&server_iter);
- ogs_assert(server_key);
- if (!strcmp(server_key, "family")) {
+ while (ogs_yaml_iter_next(&client_iter)) {
+ const char *client_key =
+ ogs_yaml_iter_key(&client_iter);
+ ogs_assert(client_key);
+ if (!strcmp(client_key, "family")) {
const char *v =
- ogs_yaml_iter_value(&server_iter);
+ ogs_yaml_iter_value(&client_iter);
if (v) family = atoi(v);
if (family != AF_UNSPEC &&
family != AF_INET &&
@@ -2106,9 +2107,9 @@ int mme_context_parse_config(void)
AF_UNSPEC, AF_INET, AF_INET6);
family = AF_UNSPEC;
}
- } else if (!strcmp(server_key, "address")) {
+ } else if (!strcmp(client_key, "address")) {
ogs_yaml_iter_t hostname_iter;
- ogs_yaml_iter_recurse(&server_iter,
+ ogs_yaml_iter_recurse(&client_iter,
&hostname_iter);
ogs_assert(ogs_yaml_iter_type(
&hostname_iter) !=
@@ -2131,26 +2132,53 @@ int mme_context_parse_config(void)
} while (ogs_yaml_iter_type(
&hostname_iter) ==
YAML_SEQUENCE_NODE);
- } else if (!strcmp(server_key, "port")) {
+ } else if (!strcmp(client_key,
+ "local_address")) {
+ ogs_yaml_iter_t local_hostname_iter;
+ ogs_yaml_iter_recurse(&client_iter,
+ &local_hostname_iter);
+ ogs_assert(ogs_yaml_iter_type(
+ &local_hostname_iter) !=
+ YAML_MAPPING_NODE);
+
+ do {
+ if (ogs_yaml_iter_type(
+ &local_hostname_iter) ==
+ YAML_SEQUENCE_NODE) {
+ if (!ogs_yaml_iter_next(
+ &local_hostname_iter))
+ break;
+ }
+
+ ogs_assert(local_hostname_num <
+ OGS_MAX_NUM_OF_HOSTNAME);
+ local_hostname
+ [local_hostname_num++] =
+ ogs_yaml_iter_value(
+ &local_hostname_iter);
+ } while (ogs_yaml_iter_type(
+ &local_hostname_iter) ==
+ YAML_SEQUENCE_NODE);
+ } else if (!strcmp(client_key, "port")) {
const char *v =
- ogs_yaml_iter_value(&server_iter);
+ ogs_yaml_iter_value(&client_iter);
if (v) {
port = atoi(v);
self.sgsap_port = port;
}
- } else if (!strcmp(server_key, "option")) {
+ } else if (!strcmp(client_key, "option")) {
rv = ogs_app_parse_sockopt_config(
- &server_iter, &option);
+ &client_iter, &option);
if (rv != OGS_OK) {
ogs_error("ogs_app_parse_sockopt_"
"config() failed");
return rv;
}
is_option = true;
- } else if (!strcmp(server_key, "map")) {
+ } else if (!strcmp(client_key, "map")) {
ogs_yaml_iter_t map_iter;
ogs_yaml_iter_recurse(
- &server_iter, &map_iter);
+ &client_iter, &map_iter);
map[map_num].tai_mcc = NULL;
map[map_num].tai_mnc = NULL;
@@ -2320,13 +2348,13 @@ int mme_context_parse_config(void)
map_num++;
- } else if (!strcmp(server_key, "tai")) {
+ } else if (!strcmp(client_key, "tai")) {
ogs_error(
"tai/lai configuraton changed to "
"map.tai/map.lai");
ogs_log_print(OGS_LOG_ERROR,
"sgsap:\n"
- " server\n"
+ " client\n"
" address: 127.0.0.2\n"
" map:\n"
" tai:\n"
@@ -2340,13 +2368,13 @@ int mme_context_parse_config(void)
" mnc: 01\n"
" lac: 43691\n");
return OGS_ERROR;
- } else if (!strcmp(server_key, "lai")) {
+ } else if (!strcmp(client_key, "lai")) {
ogs_error(
"tai/lai configuraton changed to "
"map.tai/map.lai");
ogs_log_print(OGS_LOG_ERROR,
"sgsap:\n"
- " server\n"
+ " client\n"
" address: 127.0.0.2\n"
" map:\n"
" tai:\n"
@@ -2362,7 +2390,7 @@ int mme_context_parse_config(void)
return OGS_ERROR;
} else
ogs_warn("unknown key `%s`",
- server_key);
+ client_key);
}
@@ -2386,7 +2414,20 @@ int mme_context_parse_config(void)
if (addr == NULL) continue;
- vlr = mme_vlr_add(addr,
+ local_addr = NULL;
+ for (i = 0; i < local_hostname_num; i++) {
+ rv = ogs_addaddrinfo(&local_addr,
+ family, local_hostname[i], port, 0);
+ ogs_assert(rv == OGS_OK);
+ }
+
+ ogs_filter_ip_version(&local_addr,
+ ogs_global_conf()->parameter.no_ipv4,
+ ogs_global_conf()->parameter.no_ipv6,
+ ogs_global_conf()->parameter.
+ prefer_ipv4);
+
+ vlr = mme_vlr_add(addr, local_addr,
is_option ? &option : NULL);
ogs_assert(vlr);
@@ -2409,7 +2450,7 @@ int mme_context_parse_config(void)
&csmap->lai.nas_plmn_id, &plmn_id);
csmap->lai.lac = atoi(map[i].lac);
}
- } while (ogs_yaml_iter_type(&server_array) ==
+ } while (ogs_yaml_iter_type(&client_array) ==
YAML_SEQUENCE_NODE);
} else
ogs_warn("unknown key `%s`", sgsap_key);
@@ -2737,7 +2778,10 @@ ogs_sockaddr_t *mme_pgw_addr_find_by_apn_enb(
return NULL;
}
-mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list, ogs_sockopt_t *option)
+mme_vlr_t *mme_vlr_add(
+ ogs_sockaddr_t *sa_list,
+ ogs_sockaddr_t *local_sa_list,
+ ogs_sockopt_t *option)
{
mme_vlr_t *vlr = NULL;
@@ -2751,6 +2795,7 @@ mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list, ogs_sockopt_t *option)
vlr->ostream_id = 0;
vlr->sa_list = sa_list;
+ vlr->local_sa_list = local_sa_list;
if (option) {
vlr->max_num_of_ostreams = option->sctp.sinit_num_ostreams;
vlr->option = ogs_memdup(option, sizeof *option);
@@ -2770,6 +2815,7 @@ void mme_vlr_remove(mme_vlr_t *vlr)
mme_vlr_close(vlr);
ogs_freeaddrinfo(vlr->sa_list);
+ ogs_freeaddrinfo(vlr->local_sa_list);
if (vlr->option)
ogs_free(vlr->option);
@@ -2794,13 +2840,13 @@ void mme_vlr_close(mme_vlr_t *vlr)
ogs_sctp_destroy(vlr->sock);
}
-mme_vlr_t *mme_vlr_find_by_addr(const ogs_sockaddr_t *addr)
+mme_vlr_t *mme_vlr_find_by_sock(const ogs_sock_t *sock)
{
mme_vlr_t *vlr = NULL;
- ogs_assert(addr);
+ ogs_assert(sock);
ogs_list_for_each(&self.vlr_list, vlr) {
- if (ogs_sockaddr_is_equal(vlr->addr, addr) == true)
+ if (vlr->sock == sock)
return vlr;
}
@@ -2999,7 +3045,8 @@ int mme_enb_remove(mme_enb_t *enb)
ogs_hash_set(self.enb_addr_hash,
enb->sctp.addr, sizeof(ogs_sockaddr_t), NULL);
- ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
+ if (enb->enb_id_presence == true)
+ ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
/*
* CHECK:
@@ -3046,11 +3093,14 @@ int mme_enb_set_enb_id(mme_enb_t *enb, uint32_t enb_id)
{
ogs_assert(enb);
- ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
+ if (enb->enb_id_presence == true)
+ ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), NULL);
enb->enb_id = enb_id;
ogs_hash_set(self.enb_id_hash, &enb->enb_id, sizeof(enb->enb_id), enb);
+ enb->enb_id_presence = true;
+
return OGS_OK;
}
diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h
index 2300099e4..4452bbbed 100644
--- a/src/mme/mme-context.h
+++ b/src/mme/mme-context.h
@@ -216,9 +216,9 @@ typedef struct mme_vlr_s {
uint16_t ostream_id; /* vlr_ostream_id generator */
ogs_sockaddr_t *sa_list; /* VLR SGsAP Socket Address List */
+ ogs_sockaddr_t *local_sa_list; /* VLR SGsAP Socket Local Address List */
ogs_sock_t *sock; /* VLR SGsAP Socket */
- ogs_sockaddr_t *addr; /* VLR SGsAP Connected Socket Address */
ogs_sockopt_t *option; /* VLR SGsAP Socket Option */
ogs_poll_t *poll; /* VLR SGsAP Poll */
} mme_vlr_t;
@@ -246,6 +246,7 @@ typedef struct mme_enb_s {
ogs_fsm_t sm; /* A state machine */
+ bool enb_id_presence;
uint32_t enb_id; /* eNB_ID received from eNB */
ogs_plmn_id_t plmn_id; /* eNB PLMN-ID received from eNB */
ogs_sctp_sock_t sctp; /* SCTP socket */
@@ -937,11 +938,14 @@ void mme_pgw_remove_all(void);
ogs_sockaddr_t *mme_pgw_addr_find_by_apn_enb(
ogs_list_t *list, int family, const mme_sess_t *sess);
-mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list, ogs_sockopt_t *option);
+mme_vlr_t *mme_vlr_add(
+ ogs_sockaddr_t *sa_list,
+ ogs_sockaddr_t *local_sa_list,
+ ogs_sockopt_t *option);
void mme_vlr_remove(mme_vlr_t *vlr);
void mme_vlr_remove_all(void);
void mme_vlr_close(mme_vlr_t *vlr);
-mme_vlr_t *mme_vlr_find_by_addr(const ogs_sockaddr_t *addr);
+mme_vlr_t *mme_vlr_find_by_sock(const ogs_sock_t *sock);
mme_csmap_t *mme_csmap_add(mme_vlr_t *vlr);
void mme_csmap_remove(mme_csmap_t *csmap);
diff --git a/src/mme/mme-event.c b/src/mme/mme-event.c
index 483b02b12..42ce405d7 100644
--- a/src/mme/mme-event.c
+++ b/src/mme/mme-event.c
@@ -117,7 +117,6 @@ void mme_sctp_event_push(mme_event_e id,
ogs_assert(id);
ogs_assert(sock);
- ogs_assert(addr);
e = mme_event_new(id);
ogs_assert(e);
diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c
index 7cc0d4c63..6a06fd3e2 100644
--- a/src/mme/mme-sm.c
+++ b/src/mme/mme-sm.c
@@ -970,25 +970,19 @@ cleanup:
case MME_EVENT_SGSAP_LO_SCTP_COMM_UP:
sock = e->sock;
ogs_assert(sock);
- addr = e->addr;
- ogs_assert(addr);
-
- ogs_assert(addr->ogs_sa_family == AF_INET ||
- addr->ogs_sa_family == AF_INET6);
max_num_of_ostreams = e->max_num_of_ostreams;
- vlr = mme_vlr_find_by_addr(addr);
- ogs_free(addr);
-
+ vlr = mme_vlr_find_by_sock(sock);
ogs_assert(vlr);
ogs_assert(OGS_FSM_STATE(&vlr->sm));
vlr->max_num_of_ostreams =
ogs_min(max_num_of_ostreams, vlr->max_num_of_ostreams);
- ogs_debug("VLR-SGs SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]",
- OGS_ADDR(vlr->addr, buf), vlr->max_num_of_ostreams);
+ ogs_debug("VLR-SGs SCTP_COMM_UP %s Max Num of Outbound Streams[%d]",
+ ogs_sockaddr_to_string_static(vlr->sa_list),
+ vlr->max_num_of_ostreams);
e->vlr = vlr;
ogs_fsm_dispatch(&vlr->sm, e);
@@ -997,15 +991,8 @@ cleanup:
case MME_EVENT_SGSAP_LO_CONNREFUSED:
sock = e->sock;
ogs_assert(sock);
- addr = e->addr;
- ogs_assert(addr);
-
- ogs_assert(addr->ogs_sa_family == AF_INET ||
- addr->ogs_sa_family == AF_INET6);
-
- vlr = mme_vlr_find_by_addr(addr);
- ogs_free(addr);
+ vlr = mme_vlr_find_by_sock(sock);
ogs_assert(vlr);
ogs_assert(OGS_FSM_STATE(&vlr->sm));
@@ -1013,29 +1000,22 @@ cleanup:
e->vlr = vlr;
ogs_fsm_dispatch(&vlr->sm, e);
- ogs_info("VLR-SGs[%s] connection refused!!!",
- OGS_ADDR(vlr->addr, buf));
+ ogs_info("VLR-SGs %s connection refused!!!",
+ ogs_sockaddr_to_string_static(vlr->sa_list));
} else {
- ogs_warn("VLR-SGs[%s] connection refused, Already Removed!",
- OGS_ADDR(vlr->addr, buf));
+ ogs_warn("VLR-SGs %s connection refused, Already Removed!",
+ ogs_sockaddr_to_string_static(vlr->sa_list));
}
break;
case MME_EVENT_SGSAP_MESSAGE:
sock = e->sock;
ogs_assert(sock);
- addr = e->addr;
- ogs_assert(addr);
pkbuf = e->pkbuf;
ogs_assert(pkbuf);
- ogs_assert(addr->ogs_sa_family == AF_INET ||
- addr->ogs_sa_family == AF_INET6);
-
- vlr = mme_vlr_find_by_addr(addr);
- ogs_free(addr);
-
+ vlr = mme_vlr_find_by_sock(sock);
ogs_assert(vlr);
ogs_assert(OGS_FSM_STATE(&vlr->sm));
diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c
index 3ce728382..618b42bb6 100644
--- a/src/mme/s1ap-handler.c
+++ b/src/mme/s1ap-handler.c
@@ -50,12 +50,17 @@ static bool maximum_number_of_enbs_is_reached(void)
static bool enb_plmn_id_is_foreign(mme_enb_t *enb)
{
- int i;
+ int i, j, k;
- for (i = 0; i < enb->num_of_supported_ta_list; i++) {
- if (memcmp(&enb->plmn_id, &enb->supported_ta_list[i].plmn_id,
- OGS_PLMN_ID_LEN) == 0)
- return false;
+ for (i = 0; i < mme_self()->num_of_served_gummei; i++) {
+ for (j = 0; j < mme_self()->served_gummei[i].num_of_plmn_id; j++) {
+ for (k = 0; k < enb->num_of_supported_ta_list; k++) {
+ if (memcmp(&mme_self()->served_gummei[i].plmn_id[j],
+ &enb->supported_ta_list[k].plmn_id,
+ OGS_PLMN_ID_LEN) == 0)
+ return false;
+ }
+ }
}
return true;
diff --git a/src/mme/s1ap-path.c b/src/mme/s1ap-path.c
index 0ddc68c9e..ddbdb336d 100644
--- a/src/mme/s1ap-path.c
+++ b/src/mme/s1ap-path.c
@@ -173,6 +173,12 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
ogs_assert(enb_ue);
ogs_assert(nasPdu);
+ if (nasPdu->size == 0) {
+ ogs_error("Empty NAS PDU");
+ enb_ue_remove(enb_ue);
+ return OGS_ERROR;
+ }
+
mme_ue = mme_ue_find_by_id(enb_ue->mme_ue_id);
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
diff --git a/src/mme/sgsap-path.c b/src/mme/sgsap-path.c
index a42915aa1..2fbdfb2b1 100644
--- a/src/mme/sgsap-path.c
+++ b/src/mme/sgsap-path.c
@@ -53,8 +53,7 @@ void sgsap_close(void)
}
}
-int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf,
- ogs_sockaddr_t *addr, uint16_t stream_no)
+int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, uint16_t stream_no)
{
int sent;
@@ -62,7 +61,7 @@ int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf,
ogs_assert(pkbuf);
sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len,
- addr, OGS_SCTP_SGSAP_PPID, stream_no);
+ NULL, OGS_SCTP_SGSAP_PPID, stream_no);
if (sent < 0 || sent != pkbuf->len) {
ogs_error("ogs_sctp_sendmsg(len:%d,ssn:%d) error (%d:%s)",
pkbuf->len, stream_no, errno, strerror(errno));
@@ -77,7 +76,6 @@ int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf,
int sgsap_send_to_vlr_with_sid(
mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf, uint16_t stream_no)
{
- char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;;
ogs_assert(vlr);
@@ -85,8 +83,10 @@ int sgsap_send_to_vlr_with_sid(
sock = vlr->sock;
ogs_assert(sock);
- ogs_debug(" VLR-IP[%s]", OGS_ADDR(vlr->addr, buf));
- return sgsap_send(sock, pkbuf, vlr->addr, stream_no);
+ ogs_debug(" StreamNO[%d] VLR-IP[%s]",
+ stream_no, ogs_sockaddr_to_string_static(vlr->sa_list));
+
+ return sgsap_send(sock, pkbuf, stream_no);
}
int sgsap_send_to_vlr(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf)
diff --git a/src/mme/sgsap-path.h b/src/mme/sgsap-path.h
index 0c22996a8..897019c9b 100644
--- a/src/mme/sgsap-path.h
+++ b/src/mme/sgsap-path.h
@@ -36,8 +36,7 @@ void sgsap_close(void);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr);
-int sgsap_send(ogs_sock_t *sock,
- ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);
+int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, uint16_t stream_no);
int sgsap_send_to_vlr_with_sid(
mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf, uint16_t stream_no);
diff --git a/src/mme/sgsap-sctp.c b/src/mme/sgsap-sctp.c
index d14c9287e..e7c8d340c 100644
--- a/src/mme/sgsap-sctp.c
+++ b/src/mme/sgsap-sctp.c
@@ -34,26 +34,24 @@ static void recv_handler(ogs_sock_t *sock);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr)
{
- char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;
ogs_assert(vlr);
- sock = ogs_sctp_client(SOCK_SEQPACKET, vlr->sa_list, vlr->option);
+ sock = ogs_sctp_client(SOCK_STREAM,
+ vlr->sa_list, vlr->local_sa_list, vlr->option);
if (sock) {
vlr->sock = sock;
#if HAVE_USRSCTP
- vlr->addr = vlr->sa_list;
usrsctp_set_non_blocking((struct socket *)sock, 1);
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else
- vlr->addr = &sock->remote_addr;
vlr->poll = ogs_pollset_add(ogs_app()->pollset,
OGS_POLLIN, sock->fd, lksctp_recv_handler, sock);
ogs_assert(vlr->poll);
#endif
- ogs_info("sgsap client() [%s]:%d",
- OGS_ADDR(vlr->addr, buf), OGS_PORT(vlr->addr));
+ ogs_info("sgsap client() %s",
+ ogs_sockaddr_to_string_static(vlr->sa_list));
}
return sock;
@@ -86,8 +84,6 @@ static void recv_handler(ogs_sock_t *sock)
{
ogs_pkbuf_t *pkbuf;
int size;
- ogs_sockaddr_t *addr = NULL;
- ogs_sockaddr_t from;
ogs_sctp_info_t sinfo;
int flags = 0;
@@ -97,7 +93,7 @@ static void recv_handler(ogs_sock_t *sock)
ogs_assert(pkbuf);
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
size = ogs_sctp_recvmsg(
- sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags);
+ sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags);
if (size < 0 || size >= OGS_MAX_SDU_LEN) {
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
@@ -122,12 +118,8 @@ static void recv_handler(ogs_sock_t *sock)
if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) {
ogs_debug("SCTP_COMM_UP");
- addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
- ogs_assert(addr);
- memcpy(addr, &from, sizeof(ogs_sockaddr_t));
-
sgsap_event_push(MME_EVENT_SGSAP_LO_SCTP_COMM_UP,
- sock, addr, NULL,
+ sock, NULL, NULL,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
} else if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP ||
@@ -138,12 +130,8 @@ static void recv_handler(ogs_sock_t *sock)
if (not->sn_assoc_change.sac_state == SCTP_COMM_LOST)
ogs_debug("SCTP_COMM_LOST");
- addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
- ogs_assert(addr);
- memcpy(addr, &from, sizeof(ogs_sockaddr_t));
-
sgsap_event_push(MME_EVENT_SGSAP_LO_CONNREFUSED,
- sock, addr, NULL, 0, 0);
+ sock, NULL, NULL, 0, 0);
}
break;
case SCTP_SHUTDOWN_EVENT :
@@ -166,12 +154,8 @@ static void recv_handler(ogs_sock_t *sock)
not->sn_send_failed.ssf_error);
#endif
- addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
- ogs_assert(addr);
- memcpy(addr, &from, sizeof(ogs_sockaddr_t));
-
sgsap_event_push(MME_EVENT_SGSAP_LO_CONNREFUSED,
- sock, addr, NULL, 0, 0);
+ sock, NULL, NULL, 0, 0);
break;
case SCTP_PEER_ADDR_CHANGE:
ogs_warn("SCTP_PEER_ADDR_CHANGE:[T:%d, F:0x%x, S:%d]",
@@ -193,11 +177,7 @@ static void recv_handler(ogs_sock_t *sock)
} else if (flags & MSG_EOR) {
ogs_pkbuf_trim(pkbuf, size);
- addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
- ogs_assert(addr);
- memcpy(addr, &from, sizeof(ogs_sockaddr_t));
-
- sgsap_event_push(MME_EVENT_SGSAP_MESSAGE, sock, addr, pkbuf, 0, 0);
+ sgsap_event_push(MME_EVENT_SGSAP_MESSAGE, sock, NULL, pkbuf, 0, 0);
return;
} else {
if (ogs_socket_errno != OGS_EAGAIN) {
diff --git a/src/nrf/nnrf-handler.c b/src/nrf/nnrf-handler.c
index 8ef71a588..8e0b01d8b 100644
--- a/src/nrf/nnrf-handler.c
+++ b/src/nrf/nnrf-handler.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019-2023 by Sukchan Lee
+ * Copyright (C) 2019-2024 by Sukchan Lee
*
* This file is part of Open5GS.
*
@@ -25,6 +25,15 @@ static int discover_handler(
static void handle_nf_discover_search_result(
OpenAPI_search_result_t *SearchResult);
+/**
+ * Handles NF registration in NRF. Validates the PLMN-ID against configured
+ * serving PLMN-IDs and registers the NF instance if valid.
+ *
+ * @param nf_instance The NF instance being registered.
+ * @param stream The SBI stream for communication.
+ * @param recvmsg The received SBI message.
+ * @return true if registration is successful; otherwise, false.
+ */
bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
@@ -33,6 +42,10 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
OpenAPI_nf_profile_t *NFProfile = NULL;
+ OpenAPI_lnode_t *node = NULL;
+ bool plmn_valid = false;
+ int i;
+
ogs_assert(nf_instance);
ogs_assert(stream);
ogs_assert(recvmsg);
@@ -73,6 +86,41 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
return false;
}
+ /* Validate the PLMN-ID against configured serving PLMN-IDs */
+ if (NFProfile->plmn_list) {
+ /* Set PLMN status to invalid */
+ plmn_valid = false;
+
+ if (ogs_local_conf()->num_of_serving_plmn_id > 0 && NFProfile->plmn_list) {
+ OpenAPI_list_for_each(NFProfile->plmn_list, node) {
+ OpenAPI_plmn_id_t *PlmnId = node->data;
+ if (PlmnId == NULL) {
+ continue;
+ }
+ for (i = 0; i < ogs_local_conf()->num_of_serving_plmn_id; i++) {
+ if (ogs_sbi_compare_plmn_list(
+ &ogs_local_conf()->serving_plmn_id[i],
+ PlmnId) == true) {
+ plmn_valid = true;
+ break;
+ }
+ }
+ if (plmn_valid) {
+ break;
+ }
+ }
+ }
+
+ /* Reject the registration if PLMN-ID is invalid */
+ if (!plmn_valid) {
+ ogs_error("PLMN-ID in NFProfile is not allowed");
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
+ "PLMN-ID not allowed", NULL, NULL));
+ return false;
+ }
+ }
+
ogs_nnrf_nfm_handle_nf_profile(nf_instance, NFProfile);
ogs_sbi_client_associate(nf_instance);
@@ -146,7 +194,6 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
if (ogs_local_conf()->num_of_serving_plmn_id &&
NFProfile->plmn_list == NULL) {
OpenAPI_list_t *PlmnIdList = NULL;
- int i;
PlmnIdList = OpenAPI_list_create();
ogs_assert(PlmnIdList);
@@ -208,6 +255,10 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
ogs_assert(stream);
ogs_assert(recvmsg);
+ cJSON *plmn_array = NULL, *plmn_item = NULL;
+ bool plmn_valid = false;
+ int i;
+
SWITCH(recvmsg->h.method)
CASE(OGS_SBI_HTTP_METHOD_PUT)
return nrf_nnrf_handle_nf_register(
@@ -224,14 +275,14 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
return false;
}
+ /* Iterate through the PatchItemList */
OpenAPI_list_for_each(PatchItemList, node) {
OpenAPI_patch_item_t *patch_item = node->data;
if (!patch_item) {
ogs_error("No PatchItem");
- ogs_assert(true ==
- ogs_sbi_server_send_error(stream,
- OGS_SBI_HTTP_STATUS_BAD_REQUEST,
- recvmsg, "No PatchItem", NULL, NULL));
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
+ "No PatchItem", NULL, NULL));
return false;
}
@@ -246,6 +297,102 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
break;
CASE(OGS_SBI_PATCH_PATH_LOAD)
break;
+ CASE(OGS_SBI_PATCH_PATH_PLMN_LIST)
+ /* Ensure the value is not null and is a valid JSON array */
+ if (patch_item->value && patch_item->value->json) {
+ /* Set PLMN status to invalid */
+ plmn_valid = false;
+
+ plmn_array = patch_item->value->json;
+ if (!cJSON_IsArray(plmn_array)) {
+ ogs_error("Value for /plmnList is not a JSON array");
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
+ "Invalid value for /plmnList", NULL, NULL));
+ return false;
+ }
+
+ /* Clear existing PLMN data in nf_instance */
+ memset(nf_instance->plmn_id, 0,
+ sizeof(nf_instance->plmn_id));
+ nf_instance->num_of_plmn_id = 0;
+
+ /* Iterate through the JSON array of PLMN IDs */
+ cJSON_ArrayForEach(plmn_item, plmn_array) {
+ OpenAPI_plmn_id_t plmn_id;
+ memset(&plmn_id, 0, sizeof(plmn_id));
+
+ if (nf_instance->num_of_plmn_id >=
+ OGS_ARRAY_SIZE(nf_instance->plmn_id)) {
+ ogs_error("Exceeded maximum number of PLMN IDs");
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
+ recvmsg,
+ "Too many PLMN IDs", NULL, NULL));
+ return false;
+ }
+
+ /* Parse the PLMN item */
+ plmn_id.mcc = cJSON_GetObjectItem(plmn_item, "mcc")
+ ? cJSON_GetStringValue(
+ cJSON_GetObjectItem(
+ plmn_item, "mcc"))
+ : NULL;
+ plmn_id.mnc = cJSON_GetObjectItem(plmn_item, "mnc")
+ ? cJSON_GetStringValue(
+ cJSON_GetObjectItem(
+ plmn_item, "mnc"))
+ : NULL;
+
+ if (!plmn_id.mcc || !plmn_id.mnc) {
+ ogs_error(
+ "Invalid PLMN item in /plmnList update");
+ ogs_assert(true ==
+ ogs_sbi_server_send_error(
+ stream,
+ OGS_SBI_HTTP_STATUS_BAD_REQUEST,
+ recvmsg,
+ "Invalid PLMN item", NULL,
+ NULL));
+ return false;
+ }
+
+ /*
+ * Convert OpenAPI_plmn_id_t to ogs_plmn_id_t
+ * and store in nf_instance
+ */
+ ogs_sbi_parse_plmn_id(
+ &nf_instance->
+ plmn_id[nf_instance->num_of_plmn_id],
+ &plmn_id);
+ nf_instance->num_of_plmn_id++;
+
+ /* Compare with the serving PLMN list */
+ for (i = 0;
+ i < ogs_local_conf()->num_of_serving_plmn_id;
+ i++) {
+ if (ogs_sbi_compare_plmn_list(
+ &ogs_local_conf()->serving_plmn_id[i],
+ &plmn_id) == true) {
+ plmn_valid = true;
+ break;
+ }
+ }
+ if (plmn_valid) {
+ break;
+ }
+ }
+
+ /* Reject the update if PLMN-ID is invalid */
+ if (!plmn_valid) {
+ ogs_error("PLMN-ID in NFProfile update is not allowed");
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
+ "PLMN-ID not allowed", NULL, NULL));
+ return false;
+ }
+ }
+ break;
DEFAULT
ogs_error("Unknown PatchItem.Path [%s]", patch_item->path);
END
@@ -386,6 +533,9 @@ bool nrf_nnrf_handle_nf_status_subscribe(
else if (SubscrCond->service_name)
subscription_data->subscr_cond.service_name =
ogs_strdup(SubscrCond->service_name);
+ else if (SubscrCond->nf_instance_id)
+ subscription_data->subscr_cond.nf_instance_id =
+ ogs_strdup(SubscrCond->nf_instance_id);
else {
ogs_error("No SubscrCond");
ogs_sbi_subscription_data_remove(subscription_data);
diff --git a/src/nrf/sbi-path.c b/src/nrf/sbi-path.c
index 02c0b967e..303f5c866 100644
--- a/src/nrf/sbi-path.c
+++ b/src/nrf/sbi-path.c
@@ -127,6 +127,9 @@ bool nrf_nnrf_nfm_send_nf_status_notify_all(
ogs_sbi_nf_service_is_allowed_nf_type(
nf_service, subscription_data->req_nf_type) == false)
continue;
+ } else if (subscription_data->subscr_cond.nf_instance_id) {
+ if (strcmp(subscription_data->subscr_cond.nf_instance_id, nf_instance->id) != 0)
+ continue;
}
if (subscription_data->req_nf_type &&
diff --git a/src/nssf/context.c b/src/nssf/context.c
index 6382c37cd..b5b49d150 100644
--- a/src/nssf/context.c
+++ b/src/nssf/context.c
@@ -289,7 +289,6 @@ nssf_nsi_t *nssf_nsi_add(char *nrf_id, uint8_t sst, ogs_uint24_t sd)
nssf_nsi_t *nsi = NULL;
ogs_assert(nrf_id);
- ogs_assert(sst);
ogs_pool_alloc(&nssf_nsi_pool, &nsi);
ogs_assert(nsi);
diff --git a/src/pcf/context.c b/src/pcf/context.c
index c90855357..41f1779bd 100644
--- a/src/pcf/context.c
+++ b/src/pcf/context.c
@@ -119,6 +119,7 @@ static int parse_slice_conf(
do {
ogs_app_slice_conf_t *slice_conf = NULL;
ogs_s_nssai_t s_nssai;
+ bool sst_presence = false;
bool default_indicator = false;
s_nssai.sst = 0;
@@ -131,13 +132,8 @@ static int parse_slice_conf(
if (!strcmp(slice_key, OGS_SST_STRING)) {
const char *v = ogs_yaml_iter_value(&slice_iter);
if (v) {
+ sst_presence = true;
s_nssai.sst = atoi(v);
- if (s_nssai.sst == 1 || s_nssai.sst == 2 ||
- s_nssai.sst == 3 || s_nssai.sst == 4) {
- } else {
- ogs_error("Unknown SST [%d]", s_nssai.sst);
- return OGS_ERROR;
- }
}
} else if (!strcmp(slice_key, OGS_SD_STRING)) {
const char *v = ogs_yaml_iter_value(&slice_iter);
@@ -147,7 +143,7 @@ static int parse_slice_conf(
}
}
- if (s_nssai.sst) {
+ if (sst_presence) {
slice_conf = ogs_app_slice_conf_add(policy_conf, &s_nssai);
if (!slice_conf) {
ogs_error("ogs_app_slice_conf_add() failed [SST:%d,SD:0x%x]",
diff --git a/src/pcf/nbsf-build.c b/src/pcf/nbsf-build.c
index 81680eddb..0454b8df2 100644
--- a/src/pcf/nbsf-build.c
+++ b/src/pcf/nbsf-build.c
@@ -35,15 +35,14 @@ ogs_sbi_request_t *pcf_nbsf_management_build_register(
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_nf_service_t *nf_service = NULL;
+ OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
+
int i;
ogs_assert(sess);
pcf_ue = pcf_ue_find_by_id(sess->pcf_ue_id);
ogs_assert(pcf_ue);
- nf_instance = data;
- ogs_assert(nf_instance);
-
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NBSF_MANAGEMENT;
@@ -69,6 +68,13 @@ ogs_sbi_request_t *pcf_nbsf_management_build_register(
}
PcfBinding.dnn = sess->dnn;
+ requester_nf_type = NF_INSTANCE_TYPE(ogs_sbi_self()->nf_instance);
+ ogs_assert(requester_nf_type);
+ nf_instance = ogs_sbi_nf_instance_find_by_service_type(
+ OGS_SBI_SERVICE_TYPE_NPCF_POLICYAUTHORIZATION,
+ requester_nf_type);
+ ogs_assert(nf_instance);
+
nf_service = ogs_sbi_nf_service_find_by_name(
nf_instance, (char *)OGS_SBI_SERVICE_NAME_NPCF_POLICYAUTHORIZATION);
if (!nf_service) {
@@ -127,10 +133,6 @@ ogs_sbi_request_t *pcf_nbsf_management_build_register(
}
}
- if (!sess->s_nssai.sst) {
- ogs_error("No SST");
- goto end;
- }
if (PcfIpEndPointList->count)
PcfBinding.pcf_ip_end_points = PcfIpEndPointList;
else
diff --git a/src/pcf/nbsf-handler.c b/src/pcf/nbsf-handler.c
index 7cb5a28a9..14efee5e6 100644
--- a/src/pcf/nbsf-handler.c
+++ b/src/pcf/nbsf-handler.c
@@ -24,44 +24,16 @@
bool pcf_nbsf_management_handle_register(
pcf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
- int i, rv, status = 0;
+ int rv, status = 0;
char *strerror = NULL;
pcf_ue_t *pcf_ue = NULL;
ogs_sbi_server_t *server = NULL;
- ogs_sbi_message_t sendmsg;
ogs_sbi_header_t header;
- ogs_sbi_response_t *response = NULL;
-
ogs_sbi_message_t message;
- ogs_session_data_t session_data;
-
- ogs_session_t *session = NULL;
-
OpenAPI_pcf_binding_t *PcfBinding = NULL;
- OpenAPI_sm_policy_decision_t SmPolicyDecision;
-
- OpenAPI_lnode_t *node = NULL;
-
- OpenAPI_list_t *SessRuleList = NULL;
- OpenAPI_map_t *SessRuleMap = NULL;
- OpenAPI_session_rule_t *SessionRule = NULL;
-
- OpenAPI_ambr_t AuthSessAmbr;
- OpenAPI_authorized_default_qos_t AuthDefQos;
-
- OpenAPI_list_t *PccRuleList = NULL;
- OpenAPI_map_t *PccRuleMap = NULL;
- OpenAPI_pcc_rule_t *PccRule = NULL;
-
- OpenAPI_list_t *QosDecisionList = NULL;
- OpenAPI_map_t *QosDecisionMap = NULL;
- OpenAPI_qos_data_t *QosData = NULL;
-
- OpenAPI_list_t *PolicyCtrlReqTriggers = NULL;
-
bool rc;
ogs_sbi_client_t *client = NULL;
OpenAPI_uri_scheme_e scheme = OpenAPI_uri_scheme_NULL;
@@ -78,8 +50,6 @@ bool pcf_nbsf_management_handle_register(
ogs_assert(recvmsg);
- memset(&session_data, 0, sizeof(ogs_session_data_t));
-
ogs_assert(pcf_ue->supi);
ogs_assert(sess->dnn);
@@ -158,307 +128,33 @@ bool pcf_nbsf_management_handle_register(
ogs_sbi_header_free(&header);
- rv = pcf_db_qos_data(
- pcf_ue->supi,
- sess->home.presence == true ? &sess->home.plmn_id : NULL,
- &sess->s_nssai, sess->dnn, &session_data);
- if (rv != OGS_OK) {
- strerror = ogs_msprintf("[%s:%d] Cannot find SUPI in DB",
- pcf_ue->supi, sess->psi);
- status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
- goto cleanup;
- }
+ /* Send Response for SM Policy Association establishment */
+ rc = pcf_sbi_send_smpolicycontrol_create_response(sess, stream);
+ ogs_expect(rc == true);
- session = &session_data.session;
-
- if (!session->qos.index) {
- strerror = ogs_msprintf("[%s:%d] No 5QI", pcf_ue->supi, sess->psi);
- status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
- goto cleanup;
- }
- if (!session->qos.arp.priority_level) {
- strerror = ogs_msprintf("[%s:%d] No Priority Level",
- pcf_ue->supi, sess->psi);
- status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
- goto cleanup;
- }
-
- if (!session->ambr.uplink && !session->ambr.downlink) {
- strerror = ogs_msprintf("[%s:%d] No Session-AMBR",
- pcf_ue->supi, sess->psi);
- status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
- goto cleanup;
- }
-
- memset(&SmPolicyDecision, 0, sizeof(SmPolicyDecision));
-
- PolicyCtrlReqTriggers = OpenAPI_list_create();
- ogs_assert(PolicyCtrlReqTriggers);
-
- /**************************************************************
- * Session Rule
- *************************************************************/
- SessRuleList = OpenAPI_list_create();
- ogs_assert(SessRuleList);
-
- SessionRule = ogs_calloc(1, sizeof(*SessionRule));
- ogs_assert(SessionRule);
-
- /* Only 1 SessionRule is used */
- SessionRule->sess_rule_id = (char *)"1";
-
- if (OGS_SBI_FEATURES_IS_SET(sess->smpolicycontrol_features,
- OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION)) {
- if (sess->subscribed_sess_ambr) {
- ogs_bitrate_t subscribed_sess_ambr;
-
- subscribed_sess_ambr.uplink = ogs_sbi_bitrate_from_string(
- sess->subscribed_sess_ambr->uplink);
- subscribed_sess_ambr.downlink = ogs_sbi_bitrate_from_string(
- sess->subscribed_sess_ambr->downlink);
- if (((subscribed_sess_ambr.uplink / 1000) !=
- (session->ambr.uplink / 1000)) ||
- ((subscribed_sess_ambr.downlink / 1000) !=
- (session->ambr.downlink / 1000))) {
-
- OpenAPI_list_add(PolicyCtrlReqTriggers,
- (void *)OpenAPI_policy_control_request_trigger_SE_AMBR_CH);
- }
-
- memset(&AuthSessAmbr, 0, sizeof(AuthSessAmbr));
- AuthSessAmbr.uplink = ogs_sbi_bitrate_to_string(
- session->ambr.uplink, OGS_SBI_BITRATE_KBPS);
- AuthSessAmbr.downlink = ogs_sbi_bitrate_to_string(
- session->ambr.downlink, OGS_SBI_BITRATE_KBPS);
- SessionRule->auth_sess_ambr = &AuthSessAmbr;
- }
- }
-
- if (sess->subscribed_default_qos) {
- bool triggered = false;
-
- memset(&AuthDefQos, 0, sizeof(AuthDefQos));
- AuthDefQos.arp = ogs_calloc(1, sizeof(OpenAPI_arp_t));
- ogs_assert(AuthDefQos.arp);
-
- AuthDefQos.is__5qi = true;
- AuthDefQos._5qi = session->qos.index;
- AuthDefQos.is_priority_level = true;
- AuthDefQos.priority_level = session->qos.arp.priority_level;
-
- if (session->qos.arp.pre_emption_capability ==
- OGS_5GC_PRE_EMPTION_ENABLED)
- AuthDefQos.arp->preempt_cap =
- OpenAPI_preemption_capability_MAY_PREEMPT;
- else if (session->qos.arp.pre_emption_capability ==
- OGS_5GC_PRE_EMPTION_DISABLED)
- AuthDefQos.arp->preempt_cap =
- OpenAPI_preemption_capability_NOT_PREEMPT;
- ogs_assert(AuthDefQos.arp->preempt_cap);
-
- if (session->qos.arp.pre_emption_vulnerability ==
- OGS_5GC_PRE_EMPTION_ENABLED)
- AuthDefQos.arp->preempt_vuln =
- OpenAPI_preemption_vulnerability_PREEMPTABLE;
- else if (session->qos.arp.pre_emption_vulnerability ==
- OGS_5GC_PRE_EMPTION_DISABLED)
- AuthDefQos.arp->preempt_vuln =
- OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE;
- ogs_assert(AuthDefQos.arp->preempt_vuln);
- AuthDefQos.arp->priority_level = session->qos.arp.priority_level;
-
- SessionRule->auth_def_qos = &AuthDefQos;
-
- if (sess->subscribed_default_qos->_5qi != AuthDefQos._5qi)
- triggered = true;
- if (sess->subscribed_default_qos->priority_level !=
- AuthDefQos.priority_level)
- triggered = true;
- if (sess->subscribed_default_qos->arp) {
- if (sess->subscribed_default_qos->arp->priority_level !=
- AuthDefQos.arp->priority_level)
- triggered = true;
- if (sess->subscribed_default_qos->arp->preempt_cap !=
- AuthDefQos.arp->preempt_cap)
- triggered = true;
- if (sess->subscribed_default_qos->arp->preempt_vuln !=
- AuthDefQos.arp->preempt_vuln)
- triggered = true;
-
- }
-
- if (triggered)
- OpenAPI_list_add(PolicyCtrlReqTriggers,
- (void *)OpenAPI_policy_control_request_trigger_DEF_QOS_CH);
-
- }
-
- SessRuleMap = OpenAPI_map_create(
- SessionRule->sess_rule_id, SessionRule);
- ogs_assert(SessRuleMap);
-
- OpenAPI_list_add(SessRuleList, SessRuleMap);
-
- if (SessRuleList->count)
- SmPolicyDecision.sess_rules = SessRuleList;
-
- /**************************************************************
- * PCC Rule & QoS Decision
- *************************************************************/
- PccRuleList = OpenAPI_list_create();
- ogs_assert(PccRuleList);
-
- QosDecisionList = OpenAPI_list_create();
- ogs_assert(QosDecisionList);
-
- for (i = 0; i < session_data.num_of_pcc_rule; i++) {
- ogs_pcc_rule_t *pcc_rule = &session_data.pcc_rule[i];
-
- ogs_assert(pcc_rule);
- ogs_assert(pcc_rule->id);
-
- if (!pcc_rule->num_of_flow) {
- /* No Flow */
- continue;
- }
-
- PccRule = ogs_sbi_build_pcc_rule(pcc_rule, 1);
- ogs_assert(PccRule->pcc_rule_id);
-
- PccRuleMap = OpenAPI_map_create(PccRule->pcc_rule_id, PccRule);
- ogs_assert(PccRuleMap);
-
- OpenAPI_list_add(PccRuleList, PccRuleMap);
-
- QosData = ogs_sbi_build_qos_data(pcc_rule);
- ogs_assert(QosData);
- ogs_assert(QosData->qos_id);
-
- QosDecisionMap = OpenAPI_map_create(QosData->qos_id, QosData);
- ogs_assert(QosDecisionMap);
-
- OpenAPI_list_add(QosDecisionList, QosDecisionMap);
- }
-
- if (PccRuleList->count)
- SmPolicyDecision.pcc_rules = PccRuleList;
-
- if (QosDecisionList->count)
- SmPolicyDecision.qos_decs = QosDecisionList;
-
- /* Policy Control Request Triggers */
- if (PolicyCtrlReqTriggers->count)
- SmPolicyDecision.policy_ctrl_req_triggers = PolicyCtrlReqTriggers;
-
- /* Supported Features */
- if (sess->smpolicycontrol_features) {
- SmPolicyDecision.supp_feat =
- ogs_uint64_to_string(sess->smpolicycontrol_features);
- ogs_assert(SmPolicyDecision.supp_feat);
- }
-
- memset(&header, 0, sizeof(header));
- header.service.name = (char *)OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL;
- header.api.version = (char *)OGS_SBI_API_V1;
- header.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_SM_POLICIES;
- header.resource.component[1] = sess->sm_policy_id;
-
- memset(&sendmsg, 0, sizeof(sendmsg));
- sendmsg.SmPolicyDecision = &SmPolicyDecision;
- sendmsg.http.location = ogs_sbi_server_uri(server, &header);
-
- response = ogs_sbi_build_response(
- &sendmsg, OGS_SBI_HTTP_STATUS_CREATED);
- ogs_assert(response);
- ogs_assert(true == ogs_sbi_server_send_response(stream, response));
-
- ogs_free(sendmsg.http.location);
-
- OpenAPI_list_for_each(SessRuleList, node) {
- SessRuleMap = node->data;
- if (SessRuleMap) {
- SessionRule = SessRuleMap->value;
- if (SessionRule) {
- if (SessionRule->auth_sess_ambr) {
- if (SessionRule->auth_sess_ambr->uplink)
- ogs_free(SessionRule->auth_sess_ambr->uplink);
- if (SessionRule->auth_sess_ambr->downlink)
- ogs_free(SessionRule->auth_sess_ambr->downlink);
- }
- if (SessionRule->auth_def_qos) {
- ogs_free(SessionRule->auth_def_qos->arp);
-
- }
- ogs_free(SessionRule);
- }
- ogs_free(SessRuleMap);
- }
- }
- OpenAPI_list_free(SessRuleList);
-
- OpenAPI_list_for_each(PccRuleList, node) {
- PccRuleMap = node->data;
- if (PccRuleMap) {
- PccRule = PccRuleMap->value;
- if (PccRule)
- ogs_sbi_free_pcc_rule(PccRule);
- ogs_free(PccRuleMap);
- }
- }
- OpenAPI_list_free(PccRuleList);
-
- OpenAPI_list_for_each(QosDecisionList, node) {
- QosDecisionMap = node->data;
- if (QosDecisionMap) {
- QosData = QosDecisionMap->value;
- if (QosData)
- ogs_sbi_free_qos_data(QosData);
- ogs_free(QosDecisionMap);
- }
- }
- OpenAPI_list_free(QosDecisionList);
-
- OpenAPI_list_free(PolicyCtrlReqTriggers);
-
- if (SmPolicyDecision.supp_feat)
- ogs_free(SmPolicyDecision.supp_feat);
-
- pcf_metrics_inst_by_slice_add(&pcf_ue->guami.plmn_id,
- &sess->s_nssai, PCF_METR_CTR_PA_POLICYSMASSOSUCC, 1);
-
- OGS_SESSION_DATA_FREE(&session_data);
-
- return true;
+ return rc;
cleanup:
ogs_assert(strerror);
ogs_assert(status);
ogs_error("%s", strerror);
- ogs_assert(true ==
- ogs_sbi_server_send_error(stream, status, recvmsg, strerror, NULL,
- NULL));
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, status, recvmsg, strerror, NULL, NULL));
ogs_free(strerror);
- OGS_SESSION_DATA_FREE(&session_data);
-
return false;
}
bool pcf_nbsf_management_handle_de_register(
pcf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
- ogs_sbi_message_t sendmsg;
- ogs_sbi_response_t *response = NULL;
+ bool rc;
ogs_assert(sess);
ogs_assert(stream);
- memset(&sendmsg, 0, sizeof(sendmsg));
+ rc = ogs_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT);
+ ogs_expect(rc == true);
- response = ogs_sbi_build_response(
- &sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
- ogs_assert(response);
- ogs_assert(true == ogs_sbi_server_send_response(stream, response));
-
- return true;
+ return rc;
}
diff --git a/src/pcf/nnrf-handler.c b/src/pcf/nnrf-handler.c
index ca5d6ea66..4a3247580 100644
--- a/src/pcf/nnrf-handler.c
+++ b/src/pcf/nnrf-handler.c
@@ -23,13 +23,11 @@
void pcf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{
- int r;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_object_t *sbi_object = NULL;
ogs_pool_id_t sbi_object_id = OGS_INVALID_POOL_ID;
ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
ogs_sbi_discovery_option_t *discovery_option = NULL;
- ogs_sbi_stream_t *stream = NULL;
pcf_ue_t *pcf_ue = NULL;
pcf_sess_t *sess = NULL;
@@ -55,10 +53,6 @@ void pcf_nnrf_handle_nf_discover(
discovery_option = xact->discovery_option;
- if (xact->assoc_stream_id >= OGS_MIN_POOL_ID &&
- xact->assoc_stream_id <= OGS_MAX_POOL_ID)
- stream = ogs_sbi_stream_find_by_id(xact->assoc_stream_id);
-
SearchResult = recvmsg->SearchResult;
if (!SearchResult) {
ogs_error("No SearchResult");
@@ -89,28 +83,28 @@ void pcf_nnrf_handle_nf_discover(
sess ? sess->psi : 0,
ogs_sbi_service_type_to_name(service_type),
OpenAPI_nf_type_ToString(requester_nf_type));
+
+ /* If BSF is not reachable, we ignore NBSF_MANAGMENT service */
+ if (service_type == OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT) {
+ ogs_sbi_stream_t *stream = NULL;
+
+ ogs_assert(xact->assoc_stream_id >= OGS_MIN_POOL_ID &&
+ xact->assoc_stream_id <= OGS_MAX_POOL_ID);
+ stream = ogs_sbi_stream_find_by_id(xact->assoc_stream_id);
+ ogs_assert(stream);
+
+ /* Send Response for SM Policy Association establishment */
+ ogs_expect(true ==
+ pcf_sbi_send_smpolicycontrol_create_response(sess, stream));
+
+ ogs_sbi_xact_remove(xact);
+ }
return;
}
OGS_SBI_SETUP_NF_INSTANCE(
sbi_object->service_type_array[service_type], nf_instance);
- switch (service_type) {
- case OGS_SBI_SERVICE_TYPE_NPCF_POLICYAUTHORIZATION:
- ogs_sbi_xact_remove(xact);
-
- ogs_assert(sess);
- ogs_assert(stream);
- r = pcf_sess_sbi_discover_and_send(
- OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
- pcf_nbsf_management_build_register,
- sess, stream, nf_instance);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- break;
- default:
- ogs_assert(xact->request);
- ogs_expect(true == pcf_sbi_send_request(nf_instance, xact));
- break;
- }
+ ogs_assert(xact->request);
+ ogs_expect(true == pcf_sbi_send_request(nf_instance, xact));
}
diff --git a/src/pcf/npcf-handler.c b/src/pcf/npcf-handler.c
index 845fcdd7a..dadbdf273 100644
--- a/src/pcf/npcf-handler.c
+++ b/src/pcf/npcf-handler.c
@@ -299,13 +299,6 @@ bool pcf_npcf_smpolicycontrol_handle_create(pcf_sess_t *sess,
goto cleanup;
}
- if (!sliceInfo->sst) {
- strerror = ogs_msprintf("[%s:%d] No sliceInfo->sst",
- pcf_ue->supi, sess->psi);
- status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
- goto cleanup;
- }
-
servingNetwork = SmPolicyContextData->serving_network;
if (servingNetwork) {
if (!servingNetwork->mcc) {
@@ -500,37 +493,12 @@ bool pcf_npcf_smpolicycontrol_handle_create(pcf_sess_t *sess,
if (ogs_sbi_supi_in_vplmn(pcf_ue->supi) == true) {
/* Visited PLMN */
- ogs_sbi_nf_instance_t *nf_instance = NULL;
- ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
-
- service_type = OGS_SBI_SERVICE_TYPE_NPCF_POLICYAUTHORIZATION;
-
- nf_instance = OGS_SBI_GET_NF_INSTANCE(
- sess->sbi.service_type_array[service_type]);
- if (!nf_instance) {
- OpenAPI_nf_type_e requester_nf_type =
- NF_INSTANCE_TYPE(ogs_sbi_self()->nf_instance);
- ogs_assert(requester_nf_type);
- nf_instance = ogs_sbi_nf_instance_find_by_service_type(
- service_type, requester_nf_type);
- if (nf_instance)
- OGS_SBI_SETUP_NF_INSTANCE(
- sess->sbi.service_type_array[service_type],
- nf_instance);
- }
-
- if (nf_instance) {
- r = pcf_sess_sbi_discover_and_send(
- OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
- pcf_nbsf_management_build_register,
- sess, stream, nf_instance);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- } else {
- r = pcf_sess_sbi_discover_only(sess, stream, service_type);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- }
+ r = pcf_sess_sbi_discover_and_send(
+ OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
+ pcf_nbsf_management_build_register,
+ sess, stream, NULL);
+ ogs_expect(r == OGS_OK);
+ ogs_assert(r != OGS_ERROR);
return (r == OGS_OK);
} else {
@@ -598,19 +566,17 @@ bool pcf_npcf_smpolicycontrol_handle_delete(pcf_sess_t *sess,
if (pcf_sessions_number_by_snssai_and_dnn(
pcf_ue, &sess->s_nssai, sess->dnn) > 1) {
- ogs_sbi_message_t sendmsg;
- memset(&sendmsg, 0, sizeof(sendmsg));
-
- ogs_sbi_response_t *response = ogs_sbi_build_response(
- &sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
- ogs_assert(response);
- ogs_assert(true == ogs_sbi_server_send_response(stream, response));
- } else {
+ ogs_expect(true ==
+ ogs_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT));
+ } else if (sess->binding.resource_uri) {
r = pcf_sess_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
pcf_nbsf_management_build_de_register, sess, stream, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
+ } else {
+ ogs_expect(true ==
+ ogs_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT));
}
return true;
diff --git a/src/pcf/nudr-handler.c b/src/pcf/nudr-handler.c
index 16d724ae9..be9c691b2 100644
--- a/src/pcf/nudr-handler.c
+++ b/src/pcf/nudr-handler.c
@@ -203,9 +203,6 @@ bool pcf_nudr_dr_handle_query_sm_data(
SWITCH(recvmsg->h.resource.component[3])
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
- ogs_sbi_nf_instance_t *nf_instance = NULL;
- ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
-
if (!recvmsg->SmPolicyData) {
strerror = ogs_msprintf("[%s:%d] No SmPolicyData",
pcf_ue->supi, sess->psi);
@@ -213,34 +210,12 @@ bool pcf_nudr_dr_handle_query_sm_data(
goto cleanup;
}
- service_type = OGS_SBI_SERVICE_TYPE_NPCF_POLICYAUTHORIZATION;
-
- nf_instance = OGS_SBI_GET_NF_INSTANCE(
- sess->sbi.service_type_array[service_type]);
- if (!nf_instance) {
- OpenAPI_nf_type_e requester_nf_type =
- NF_INSTANCE_TYPE(ogs_sbi_self()->nf_instance);
- ogs_assert(requester_nf_type);
- nf_instance = ogs_sbi_nf_instance_find_by_service_type(
- service_type, requester_nf_type);
- if (nf_instance)
- OGS_SBI_SETUP_NF_INSTANCE(
- sess->sbi.service_type_array[service_type],
- nf_instance);
- }
-
- if (nf_instance) {
- r = pcf_sess_sbi_discover_and_send(
- OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
- pcf_nbsf_management_build_register,
- sess, stream, nf_instance);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- } else {
- r = pcf_sess_sbi_discover_only(sess, stream, service_type);
- ogs_expect(r == OGS_OK);
- ogs_assert(r != OGS_ERROR);
- }
+ r = pcf_sess_sbi_discover_and_send(
+ OGS_SBI_SERVICE_TYPE_NBSF_MANAGEMENT, NULL,
+ pcf_nbsf_management_build_register,
+ sess, stream, NULL);
+ ogs_expect(r == OGS_OK);
+ ogs_assert(r != OGS_ERROR);
return true;
diff --git a/src/pcf/sbi-path.c b/src/pcf/sbi-path.c
index fe18a4026..4d358e45e 100644
--- a/src/pcf/sbi-path.c
+++ b/src/pcf/sbi-path.c
@@ -189,31 +189,6 @@ int pcf_ue_sbi_discover_and_send(
return OGS_OK;
}
-int pcf_sess_sbi_discover_only(
- pcf_sess_t *sess, ogs_sbi_stream_t *stream,
- ogs_sbi_service_type_e service_type)
-{
- ogs_sbi_xact_t *xact = NULL;
-
- ogs_assert(sess);
- ogs_assert(service_type);
-
- xact = ogs_sbi_xact_add(
- 0, &sess->sbi, service_type, NULL, NULL, NULL, NULL);
- if (!xact) {
- ogs_error("ogs_sbi_xact_add() failed");
- return OGS_ERROR;
- }
-
- if (stream) {
- xact->assoc_stream_id = ogs_sbi_id_from_stream(stream);
- ogs_assert(xact->assoc_stream_id >= OGS_MIN_POOL_ID &&
- xact->assoc_stream_id <= OGS_MAX_POOL_ID);
- }
-
- return ogs_sbi_discover_only(xact);
-}
-
int pcf_sess_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
@@ -307,6 +282,340 @@ bool pcf_sbi_send_am_policy_control_notify(pcf_ue_t *pcf_ue)
return rc;
}
+bool pcf_sbi_send_smpolicycontrol_create_response(
+ pcf_sess_t *sess, ogs_sbi_stream_t *stream)
+{
+ int i, rv, status = 0;
+ char *strerror = NULL;
+ pcf_ue_t *pcf_ue = NULL;
+ ogs_sbi_server_t *server = NULL;
+
+ ogs_sbi_message_t sendmsg;
+ ogs_sbi_header_t header;
+ ogs_sbi_response_t *response = NULL;
+
+ ogs_session_data_t session_data;
+
+ ogs_session_t *session = NULL;
+
+ OpenAPI_sm_policy_decision_t SmPolicyDecision;
+
+ OpenAPI_lnode_t *node = NULL;
+
+ OpenAPI_list_t *SessRuleList = NULL;
+ OpenAPI_map_t *SessRuleMap = NULL;
+ OpenAPI_session_rule_t *SessionRule = NULL;
+
+ OpenAPI_ambr_t AuthSessAmbr;
+ OpenAPI_authorized_default_qos_t AuthDefQos;
+
+ OpenAPI_list_t *PccRuleList = NULL;
+ OpenAPI_map_t *PccRuleMap = NULL;
+ OpenAPI_pcc_rule_t *PccRule = NULL;
+
+ OpenAPI_list_t *QosDecisionList = NULL;
+ OpenAPI_map_t *QosDecisionMap = NULL;
+ OpenAPI_qos_data_t *QosData = NULL;
+
+ OpenAPI_list_t *PolicyCtrlReqTriggers = NULL;
+
+ ogs_assert(sess);
+ pcf_ue = pcf_ue_find_by_id(sess->pcf_ue_id);
+ ogs_assert(pcf_ue);
+ ogs_assert(stream);
+ server = ogs_sbi_server_from_stream(stream);
+ ogs_assert(server);
+
+ memset(&session_data, 0, sizeof(ogs_session_data_t));
+
+ ogs_assert(pcf_ue->supi);
+ ogs_assert(sess->dnn);
+
+ rv = pcf_db_qos_data(
+ pcf_ue->supi,
+ sess->home.presence == true ? &sess->home.plmn_id : NULL,
+ &sess->s_nssai, sess->dnn, &session_data);
+ if (rv != OGS_OK) {
+ strerror = ogs_msprintf("[%s:%d] Cannot find SUPI in DB",
+ pcf_ue->supi, sess->psi);
+ status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
+ goto cleanup;
+ }
+
+ session = &session_data.session;
+
+ if (!session->qos.index) {
+ strerror = ogs_msprintf("[%s:%d] No 5QI", pcf_ue->supi, sess->psi);
+ status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
+ goto cleanup;
+ }
+ if (!session->qos.arp.priority_level) {
+ strerror = ogs_msprintf("[%s:%d] No Priority Level",
+ pcf_ue->supi, sess->psi);
+ status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
+ goto cleanup;
+ }
+
+ if (!session->ambr.uplink && !session->ambr.downlink) {
+ strerror = ogs_msprintf("[%s:%d] No Session-AMBR",
+ pcf_ue->supi, sess->psi);
+ status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
+ goto cleanup;
+ }
+
+ memset(&SmPolicyDecision, 0, sizeof(SmPolicyDecision));
+
+ PolicyCtrlReqTriggers = OpenAPI_list_create();
+ ogs_assert(PolicyCtrlReqTriggers);
+
+ /**************************************************************
+ * Session Rule
+ *************************************************************/
+ SessRuleList = OpenAPI_list_create();
+ ogs_assert(SessRuleList);
+
+ SessionRule = ogs_calloc(1, sizeof(*SessionRule));
+ ogs_assert(SessionRule);
+
+ /* Only 1 SessionRule is used */
+ SessionRule->sess_rule_id = (char *)"1";
+
+ if (OGS_SBI_FEATURES_IS_SET(sess->smpolicycontrol_features,
+ OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION)) {
+ if (sess->subscribed_sess_ambr) {
+ ogs_bitrate_t subscribed_sess_ambr;
+
+ subscribed_sess_ambr.uplink = ogs_sbi_bitrate_from_string(
+ sess->subscribed_sess_ambr->uplink);
+ subscribed_sess_ambr.downlink = ogs_sbi_bitrate_from_string(
+ sess->subscribed_sess_ambr->downlink);
+ if (((subscribed_sess_ambr.uplink / 1000) !=
+ (session->ambr.uplink / 1000)) ||
+ ((subscribed_sess_ambr.downlink / 1000) !=
+ (session->ambr.downlink / 1000))) {
+
+ OpenAPI_list_add(PolicyCtrlReqTriggers,
+ (void *)OpenAPI_policy_control_request_trigger_SE_AMBR_CH);
+ }
+
+ memset(&AuthSessAmbr, 0, sizeof(AuthSessAmbr));
+ AuthSessAmbr.uplink = ogs_sbi_bitrate_to_string(
+ session->ambr.uplink, OGS_SBI_BITRATE_KBPS);
+ AuthSessAmbr.downlink = ogs_sbi_bitrate_to_string(
+ session->ambr.downlink, OGS_SBI_BITRATE_KBPS);
+ SessionRule->auth_sess_ambr = &AuthSessAmbr;
+ }
+ }
+
+ if (sess->subscribed_default_qos) {
+ bool triggered = false;
+
+ memset(&AuthDefQos, 0, sizeof(AuthDefQos));
+ AuthDefQos.arp = ogs_calloc(1, sizeof(OpenAPI_arp_t));
+ ogs_assert(AuthDefQos.arp);
+
+ AuthDefQos.is__5qi = true;
+ AuthDefQos._5qi = session->qos.index;
+ AuthDefQos.is_priority_level = true;
+ AuthDefQos.priority_level = session->qos.arp.priority_level;
+
+ if (session->qos.arp.pre_emption_capability ==
+ OGS_5GC_PRE_EMPTION_ENABLED)
+ AuthDefQos.arp->preempt_cap =
+ OpenAPI_preemption_capability_MAY_PREEMPT;
+ else if (session->qos.arp.pre_emption_capability ==
+ OGS_5GC_PRE_EMPTION_DISABLED)
+ AuthDefQos.arp->preempt_cap =
+ OpenAPI_preemption_capability_NOT_PREEMPT;
+ ogs_assert(AuthDefQos.arp->preempt_cap);
+
+ if (session->qos.arp.pre_emption_vulnerability ==
+ OGS_5GC_PRE_EMPTION_ENABLED)
+ AuthDefQos.arp->preempt_vuln =
+ OpenAPI_preemption_vulnerability_PREEMPTABLE;
+ else if (session->qos.arp.pre_emption_vulnerability ==
+ OGS_5GC_PRE_EMPTION_DISABLED)
+ AuthDefQos.arp->preempt_vuln =
+ OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE;
+ ogs_assert(AuthDefQos.arp->preempt_vuln);
+ AuthDefQos.arp->priority_level = session->qos.arp.priority_level;
+
+ SessionRule->auth_def_qos = &AuthDefQos;
+
+ if (sess->subscribed_default_qos->_5qi != AuthDefQos._5qi)
+ triggered = true;
+ if (sess->subscribed_default_qos->priority_level !=
+ AuthDefQos.priority_level)
+ triggered = true;
+ if (sess->subscribed_default_qos->arp) {
+ if (sess->subscribed_default_qos->arp->priority_level !=
+ AuthDefQos.arp->priority_level)
+ triggered = true;
+ if (sess->subscribed_default_qos->arp->preempt_cap !=
+ AuthDefQos.arp->preempt_cap)
+ triggered = true;
+ if (sess->subscribed_default_qos->arp->preempt_vuln !=
+ AuthDefQos.arp->preempt_vuln)
+ triggered = true;
+
+ }
+
+ if (triggered)
+ OpenAPI_list_add(PolicyCtrlReqTriggers,
+ (void *)OpenAPI_policy_control_request_trigger_DEF_QOS_CH);
+
+ }
+
+ SessRuleMap = OpenAPI_map_create(
+ SessionRule->sess_rule_id, SessionRule);
+ ogs_assert(SessRuleMap);
+
+ OpenAPI_list_add(SessRuleList, SessRuleMap);
+
+ if (SessRuleList->count)
+ SmPolicyDecision.sess_rules = SessRuleList;
+
+ /**************************************************************
+ * PCC Rule & QoS Decision
+ *************************************************************/
+ PccRuleList = OpenAPI_list_create();
+ ogs_assert(PccRuleList);
+
+ QosDecisionList = OpenAPI_list_create();
+ ogs_assert(QosDecisionList);
+
+ for (i = 0; i < session_data.num_of_pcc_rule; i++) {
+ ogs_pcc_rule_t *pcc_rule = &session_data.pcc_rule[i];
+
+ ogs_assert(pcc_rule);
+ ogs_assert(pcc_rule->id);
+
+ if (!pcc_rule->num_of_flow) {
+ /* No Flow */
+ continue;
+ }
+
+ PccRule = ogs_sbi_build_pcc_rule(pcc_rule, 1);
+ ogs_assert(PccRule->pcc_rule_id);
+
+ PccRuleMap = OpenAPI_map_create(PccRule->pcc_rule_id, PccRule);
+ ogs_assert(PccRuleMap);
+
+ OpenAPI_list_add(PccRuleList, PccRuleMap);
+
+ QosData = ogs_sbi_build_qos_data(pcc_rule);
+ ogs_assert(QosData);
+ ogs_assert(QosData->qos_id);
+
+ QosDecisionMap = OpenAPI_map_create(QosData->qos_id, QosData);
+ ogs_assert(QosDecisionMap);
+
+ OpenAPI_list_add(QosDecisionList, QosDecisionMap);
+ }
+
+ if (PccRuleList->count)
+ SmPolicyDecision.pcc_rules = PccRuleList;
+
+ if (QosDecisionList->count)
+ SmPolicyDecision.qos_decs = QosDecisionList;
+
+ /* Policy Control Request Triggers */
+ if (PolicyCtrlReqTriggers->count)
+ SmPolicyDecision.policy_ctrl_req_triggers = PolicyCtrlReqTriggers;
+
+ /* Supported Features */
+ if (sess->smpolicycontrol_features) {
+ SmPolicyDecision.supp_feat =
+ ogs_uint64_to_string(sess->smpolicycontrol_features);
+ ogs_assert(SmPolicyDecision.supp_feat);
+ }
+
+ memset(&header, 0, sizeof(header));
+ header.service.name = (char *)OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL;
+ header.api.version = (char *)OGS_SBI_API_V1;
+ header.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_SM_POLICIES;
+ header.resource.component[1] = sess->sm_policy_id;
+
+ memset(&sendmsg, 0, sizeof(sendmsg));
+ sendmsg.SmPolicyDecision = &SmPolicyDecision;
+ sendmsg.http.location = ogs_sbi_server_uri(server, &header);
+
+ response = ogs_sbi_build_response(
+ &sendmsg, OGS_SBI_HTTP_STATUS_CREATED);
+ ogs_assert(response);
+ ogs_assert(true == ogs_sbi_server_send_response(stream, response));
+
+ ogs_free(sendmsg.http.location);
+
+ OpenAPI_list_for_each(SessRuleList, node) {
+ SessRuleMap = node->data;
+ if (SessRuleMap) {
+ SessionRule = SessRuleMap->value;
+ if (SessionRule) {
+ if (SessionRule->auth_sess_ambr) {
+ if (SessionRule->auth_sess_ambr->uplink)
+ ogs_free(SessionRule->auth_sess_ambr->uplink);
+ if (SessionRule->auth_sess_ambr->downlink)
+ ogs_free(SessionRule->auth_sess_ambr->downlink);
+ }
+ if (SessionRule->auth_def_qos) {
+ ogs_free(SessionRule->auth_def_qos->arp);
+
+ }
+ ogs_free(SessionRule);
+ }
+ ogs_free(SessRuleMap);
+ }
+ }
+ OpenAPI_list_free(SessRuleList);
+
+ OpenAPI_list_for_each(PccRuleList, node) {
+ PccRuleMap = node->data;
+ if (PccRuleMap) {
+ PccRule = PccRuleMap->value;
+ if (PccRule)
+ ogs_sbi_free_pcc_rule(PccRule);
+ ogs_free(PccRuleMap);
+ }
+ }
+ OpenAPI_list_free(PccRuleList);
+
+ OpenAPI_list_for_each(QosDecisionList, node) {
+ QosDecisionMap = node->data;
+ if (QosDecisionMap) {
+ QosData = QosDecisionMap->value;
+ if (QosData)
+ ogs_sbi_free_qos_data(QosData);
+ ogs_free(QosDecisionMap);
+ }
+ }
+ OpenAPI_list_free(QosDecisionList);
+
+ OpenAPI_list_free(PolicyCtrlReqTriggers);
+
+ if (SmPolicyDecision.supp_feat)
+ ogs_free(SmPolicyDecision.supp_feat);
+
+ pcf_metrics_inst_by_slice_add(&pcf_ue->guami.plmn_id,
+ &sess->s_nssai, PCF_METR_CTR_PA_POLICYSMASSOSUCC, 1);
+
+ OGS_SESSION_DATA_FREE(&session_data);
+
+ return true;
+
+cleanup:
+ ogs_assert(strerror);
+ ogs_assert(status);
+ ogs_error("%s", strerror);
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, status, NULL, strerror, NULL, NULL));
+ ogs_free(strerror);
+
+ OGS_SESSION_DATA_FREE(&session_data);
+
+ return false;
+}
+
bool pcf_sbi_send_smpolicycontrol_update_notify(
pcf_sess_t *sess, OpenAPI_sm_policy_decision_t *SmPolicyDecision)
{
diff --git a/src/pcf/sbi-path.h b/src/pcf/sbi-path.h
index 069921244..b72465964 100644
--- a/src/pcf/sbi-path.h
+++ b/src/pcf/sbi-path.h
@@ -45,11 +45,10 @@ int pcf_sess_sbi_discover_and_send(
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(pcf_sess_t *sess, void *data),
pcf_sess_t *sess, ogs_sbi_stream_t *stream, void *data);
-int pcf_sess_sbi_discover_only(
- pcf_sess_t *sess, ogs_sbi_stream_t *stream,
- ogs_sbi_service_type_e service_type);
bool pcf_sbi_send_am_policy_control_notify(pcf_ue_t *pcf_ue);
+bool pcf_sbi_send_smpolicycontrol_create_response(
+ pcf_sess_t *sess, ogs_sbi_stream_t *stream);
bool pcf_sbi_send_smpolicycontrol_update_notify(
pcf_sess_t *sess, OpenAPI_sm_policy_decision_t *SmPolicyDecision);
bool pcf_sbi_send_smpolicycontrol_delete_notify(
diff --git a/src/pcf/sm-sm.c b/src/pcf/sm-sm.c
index edd0f07fa..1693c1af8 100644
--- a/src/pcf/sm-sm.c
+++ b/src/pcf/sm-sm.c
@@ -291,8 +291,22 @@ void pcf_sm_state_operational(ogs_fsm_t *s, pcf_event_t *e)
} else {
SWITCH(message->h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
- pcf_nbsf_management_handle_register(
- sess, stream, message);
+ if (message->res_status ==
+ OGS_SBI_HTTP_STATUS_CREATED) {
+ pcf_nbsf_management_handle_register(
+ sess, stream, message);
+ } else {
+ ogs_error("[%s:%d] HTTP response error [%d]",
+ pcf_ue->supi, sess->psi, message->res_status);
+
+ /*
+ * Send Response
+ * for SM Policy Association establishment
+ */
+ ogs_expect(true ==
+ pcf_sbi_send_smpolicycontrol_create_response(
+ sess, stream));
+ }
break;
DEFAULT
ogs_error("[%s:%d] Unknown method [%s]",
diff --git a/src/scp/sbi-path.c b/src/scp/sbi-path.c
index 6f098cd1c..6e91aedf5 100644
--- a/src/scp/sbi-path.c
+++ b/src/scp/sbi-path.c
@@ -68,11 +68,11 @@ int scp_sbi_open(void)
}
/* Check if Next-SCP's client */
- if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_AUTO) {
+ if (ogs_sbi_self()->client_delegated_config.scp.next ==
+ OGS_SBI_CLIENT_DELEGATED_AUTO) {
next_scp = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
- } else if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_YES) {
+ } else if (ogs_sbi_self()->client_delegated_config.scp.next ==
+ OGS_SBI_CLIENT_DELEGATED_YES) {
next_scp = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
ogs_assert(next_scp);
}
@@ -153,11 +153,11 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
}
/* Next-SCP client */
- if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_AUTO) {
+ if (ogs_sbi_self()->client_delegated_config.scp.next ==
+ OGS_SBI_CLIENT_DELEGATED_AUTO) {
next_scp = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
- } else if (ogs_sbi_self()->discovery_config.delegated ==
- OGS_SBI_DISCOVERY_DELEGATED_YES) {
+ } else if (ogs_sbi_self()->client_delegated_config.scp.next ==
+ OGS_SBI_CLIENT_DELEGATED_YES) {
next_scp = NF_INSTANCE_CLIENT(ogs_sbi_self()->scp_instance);
ogs_assert(next_scp);
}
@@ -586,16 +586,6 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
return OGS_ERROR;
}
- assoc->request = request;
- ogs_assert(assoc->request);
- assoc->service_type = service_type;
- ogs_assert(assoc->service_type);
-
- assoc->target_nf_type = target_nf_type;
- ogs_assert(assoc->target_nf_type);
- assoc->requester_nf_type = requester_nf_type;
- ogs_assert(assoc->requester_nf_type);
-
if (!discovery_option->num_of_service_names) {
ogs_error("No service names");
scp_assoc_remove(assoc);
@@ -626,6 +616,16 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
"in TS29.500");
}
+ assoc->request = request;
+ ogs_assert(assoc->request);
+ assoc->service_type = service_type;
+ ogs_assert(assoc->service_type);
+
+ assoc->target_nf_type = target_nf_type;
+ ogs_assert(assoc->target_nf_type);
+ assoc->requester_nf_type = requester_nf_type;
+ ogs_assert(assoc->requester_nf_type);
+
if (false == send_discover(nrf_client, nf_discover_handler, assoc)) {
ogs_error("send_discover() failed");
scp_assoc_remove(assoc);
@@ -717,7 +717,7 @@ static int response_handler(
static int nf_discover_handler(
int status, ogs_sbi_response_t *response, void *data)
{
- int rv;
+ int rv, res_status;
char *strerror = NULL;
ogs_sbi_message_t message;
@@ -777,16 +777,19 @@ static int nf_discover_handler(
rv = ogs_sbi_parse_response(&message, response);
if (rv != OGS_OK) {
strerror = ogs_msprintf("cannot parse HTTP response");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
if (message.res_status != OGS_SBI_HTTP_STATUS_OK) {
strerror = ogs_msprintf("NF-Discover failed [%d]", message.res_status);
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
if (!message.SearchResult) {
strerror = ogs_msprintf("No SearchResult");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
@@ -798,7 +801,7 @@ static int nf_discover_handler(
strerror = ogs_msprintf("(NF discover) No NF-Instance [%s:%s]",
ogs_sbi_service_type_to_name(service_type),
OpenAPI_nf_type_ToString(requester_nf_type));
-
+ res_status = OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT;
goto cleanup;
}
@@ -811,7 +814,7 @@ static int nf_discover_handler(
strerror = ogs_msprintf("(NF discover) No client [%s:%s]",
ogs_sbi_service_type_to_name(service_type),
OpenAPI_nf_type_ToString(requester_nf_type));
-
+ res_status = OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT;
goto cleanup;
}
@@ -825,6 +828,7 @@ static int nf_discover_handler(
if (!sepp_client) {
ogs_error("No SEPP [%s]", client->fqdn);
strerror = ogs_msprintf("No SEPP [%s]", client->fqdn);
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
@@ -839,6 +843,7 @@ static int nf_discover_handler(
if (false == send_request(
client, response_handler, request, false, assoc)) {
strerror = ogs_msprintf("send_request() failed");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
@@ -854,10 +859,8 @@ cleanup:
scp_assoc_remove(assoc);
if (stream) {
- ogs_assert(true ==
- ogs_sbi_server_send_error(
- stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL,
- NULL));
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, res_status, NULL, strerror, NULL, NULL));
} else
ogs_error("STREAM has already been removed [%d]", stream_id);
@@ -872,7 +875,7 @@ cleanup:
static int sepp_discover_handler(
int status, ogs_sbi_response_t *response, void *data)
{
- int rv;
+ int rv, res_status;
char *strerror = NULL;
ogs_sbi_message_t message;
@@ -914,16 +917,19 @@ static int sepp_discover_handler(
rv = ogs_sbi_parse_response(&message, response);
if (rv != OGS_OK) {
strerror = ogs_msprintf("cannot parse HTTP response");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
if (message.res_status != OGS_SBI_HTTP_STATUS_OK) {
strerror = ogs_msprintf("NF-Discover failed [%d]", message.res_status);
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
if (!message.SearchResult) {
strerror = ogs_msprintf("No SearchResult");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
@@ -935,6 +941,7 @@ static int sepp_discover_handler(
sepp_client = NF_INSTANCE_CLIENT(ogs_sbi_self()->sepp_instance);
if (!sepp_client) {
strerror = ogs_msprintf("No SEPP");
+ res_status = OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT;
goto cleanup;
}
@@ -945,6 +952,7 @@ static int sepp_discover_handler(
if (false == send_request(
sepp_client, response_handler, request, false, assoc)) {
strerror = ogs_msprintf("send_request() failed");
+ res_status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
goto cleanup;
}
@@ -960,10 +968,8 @@ cleanup:
scp_assoc_remove(assoc);
if (stream) {
- ogs_assert(true ==
- ogs_sbi_server_send_error(
- stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL,
- NULL));
+ ogs_assert(true == ogs_sbi_server_send_error(
+ stream, res_status, NULL, strerror, NULL, NULL));
} else
ogs_error("STREAM has already been removed [%d]", stream_id);
diff --git a/src/sgwc/context.c b/src/sgwc/context.c
index 3c19ad7be..758486ef7 100644
--- a/src/sgwc/context.c
+++ b/src/sgwc/context.c
@@ -408,8 +408,6 @@ static ogs_pfcp_node_t *selected_sgwu_node(
void sgwc_sess_select_sgwu(sgwc_sess_t *sess)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_assert(sess);
/*
@@ -425,8 +423,9 @@ void sgwc_sess_select_sgwu(sgwc_sess_t *sess)
selected_sgwu_node(ogs_pfcp_self()->pfcp_node, sess);
ogs_assert(ogs_pfcp_self()->pfcp_node);
OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->pfcp_node);
- ogs_debug("UE using SGW-U on IP[%s]",
- OGS_ADDR(&ogs_pfcp_self()->pfcp_node->addr, buf));
+ ogs_debug("UE using SGW-U on IP %s",
+ ogs_sockaddr_to_string_static(
+ ogs_pfcp_self()->pfcp_node->addr_list));
}
int sgwc_sess_remove(sgwc_sess_t *sess)
@@ -761,14 +760,15 @@ sgwc_tunnel_t *sgwc_tunnel_add(
else
tunnel->local_teid = pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &tunnel->local_addr, &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ &tunnel->local_addr, sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &tunnel->local_addr6, &sess->pfcp_node->addr));
+ &tunnel->local_addr6, sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
diff --git a/src/sgwc/pfcp-path.c b/src/sgwc/pfcp-path.c
index b0b12aadd..5712fa98c 100644
--- a/src/sgwc/pfcp-path.c
+++ b/src/sgwc/pfcp-path.c
@@ -61,8 +61,12 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from;
ogs_pfcp_node_t *node = NULL;
+ ogs_pfcp_message_t *message = NULL;
ogs_pfcp_header_t *h = NULL;
+ ogs_pfcp_status_e pfcp_status;;
+ ogs_pfcp_node_id_t node_id;
+
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
@@ -102,28 +106,105 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
e = sgwc_event_new(SGWC_EVT_SXA_MESSAGE);
ogs_assert(e);
- node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- ogs_error("No memory: ogs_pfcp_node_add() failed");
- ogs_pkbuf_free(e->pkbuf);
- sgwc_event_free(e);
- return;
- }
-
- node->sock = data;
- pfcp_node_fsm_init(node, false);
+ /*
+ * Issue #1911
+ *
+ * Because ogs_pfcp_message_t is over 80kb in size,
+ * it can cause stack overflow.
+ * To avoid this, the pfcp_message structure uses heap memory.
+ */
+ if ((message = ogs_pfcp_parse_msg(pkbuf)) == NULL) {
+ ogs_error("ogs_pfcp_parse_msg() failed");
+ ogs_pkbuf_free(pkbuf);
+ sgwc_event_free(e);
+ return;
}
+
+ pfcp_status = ogs_pfcp_extract_node_id(message, &node_id);
+ switch (pfcp_status) {
+ case OGS_PFCP_STATUS_SUCCESS:
+ case OGS_PFCP_STATUS_NODE_ID_NONE:
+ case OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT:
+ ogs_debug("ogs_pfcp_extract_node_id() "
+ "type [%d] pfcp_status [%d] node_id [%s] from %s",
+ message->h.type, pfcp_status,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ break;
+
+ case OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_FOUND:
+ case OGS_PFCP_ERROR_UNKNOWN_MESSAGE:
+ ogs_error("ogs_pfcp_extract_node_id() failed "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+
+ default:
+ ogs_error("Unexpected pfcp_status "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+
+ node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL, &from);
+ if (!node) {
+ if (message->h.type == OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE ||
+ message->h.type == OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE) {
+ ogs_assert(pfcp_status == OGS_PFCP_STATUS_SUCCESS);
+ node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list,
+ &node_id, &from);
+ if (!node) {
+ ogs_error("No memory: ogs_pfcp_node_add() failed");
+ goto cleanup;
+ }
+ ogs_debug("Added PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+
+ pfcp_node_fsm_init(node, false);
+
+ } else {
+ ogs_error("Cannot find PFCP-Node: type [%d] node_id %s from %s",
+ message->h.type,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+ } else {
+ ogs_debug("Found PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ ogs_expect(OGS_OK == ogs_pfcp_node_merge(
+ node,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL,
+ &from));
+ ogs_debug("Merged PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ }
+
e->pfcp_node = node;
e->pkbuf = pkbuf;
+ e->pfcp_message = message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
- ogs_pkbuf_free(e->pkbuf);
- sgwc_event_free(e);
+ goto cleanup;
}
+
+ return;
+
+cleanup:
+ ogs_pkbuf_free(pkbuf);
+ ogs_pfcp_message_free(message);
+ sgwc_event_free(e);
}
int sgwc_pfcp_open(void)
diff --git a/src/sgwc/pfcp-sm.c b/src/sgwc/pfcp-sm.c
index e0357ae61..bf9ed5aa2 100644
--- a/src/sgwc/pfcp-sm.c
+++ b/src/sgwc/pfcp-sm.c
@@ -25,7 +25,6 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data);
void sgwc_pfcp_state_initial(ogs_fsm_t *s, sgwc_event_t *e)
{
- int rv;
ogs_pfcp_node_t *node = NULL;
ogs_assert(s);
@@ -36,10 +35,6 @@ void sgwc_pfcp_state_initial(ogs_fsm_t *s, sgwc_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- rv = ogs_pfcp_connect(
- ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
- ogs_assert(rv == OGS_OK);
-
node->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
sgwc_timer_pfcp_no_heartbeat, node);
ogs_assert(node->t_no_heartbeat);
@@ -63,14 +58,10 @@ void sgwc_pfcp_state_final(ogs_fsm_t *s, sgwc_event_t *e)
void sgwc_pfcp_state_will_associate(ogs_fsm_t *s, sgwc_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
-
ogs_assert(s);
ogs_assert(e);
@@ -78,8 +69,6 @@ void sgwc_pfcp_state_will_associate(ogs_fsm_t *s, sgwc_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
@@ -103,8 +92,8 @@ void sgwc_pfcp_state_will_associate(ogs_fsm_t *s, sgwc_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- ogs_warn("Retry association with peer [%s]:%d failed",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("Retry association with peer failed %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
@@ -159,13 +148,10 @@ void sgwc_pfcp_state_will_associate(ogs_fsm_t *s, sgwc_event_t *e)
void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
sgwc_sess_t *sess = NULL;
ogs_assert(s);
@@ -175,14 +161,11 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
- ogs_info("PFCP associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_start(node->t_no_heartbeat,
ogs_local_conf()->time.message.pfcp.no_heartbeat_duration);
ogs_assert(OGS_OK ==
@@ -195,9 +178,8 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
}
break;
case OGS_FSM_EXIT_SIG:
- ogs_info("PFCP de-associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP de-associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_stop(node->t_no_heartbeat);
break;
case SGWC_EVT_SXA_MESSAGE:
@@ -274,16 +256,14 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
}
break;
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
- ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[REQ] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_cp_handle_association_setup_request(node, xact,
&message->pfcp_association_setup_request);
break;
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
- ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[RSP] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_cp_handle_association_setup_response(node, xact,
&message->pfcp_association_setup_response);
break;
@@ -359,8 +339,8 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
}
break;
case SGWC_EVT_SXA_NO_HEARTBEAT:
- ogs_warn("No Heartbeat from SGW-U [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("No Heartbeat from SGW-U %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
OGS_FSM_TRAN(s, sgwc_pfcp_state_will_associate);
break;
default:
diff --git a/src/sgwc/sgwc-sm.c b/src/sgwc/sgwc-sm.c
index 1d24945eb..96c7d1272 100644
--- a/src/sgwc/sgwc-sm.c
+++ b/src/sgwc/sgwc-sm.c
@@ -89,23 +89,12 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
pfcp_node = e->pfcp_node;
ogs_assert(pfcp_node);
ogs_assert(OGS_FSM_STATE(&pfcp_node->sm));
- /*
- * Issue #1911
- *
- * Because ogs_pfcp_message_t is over 80kb in size,
- * it can cause stack overflow.
- * To avoid this, the pfcp_message structure uses heap memory.
- */
- if ((pfcp_message = ogs_pfcp_parse_msg(recvbuf)) == NULL) {
- ogs_error("ogs_pfcp_parse_msg() failed");
- ogs_pkbuf_free(recvbuf);
- break;
- }
-
rv = ogs_pfcp_xact_receive(pfcp_node, &pfcp_message->h, &pfcp_xact);
if (rv != OGS_OK) {
ogs_pkbuf_free(recvbuf);
@@ -113,7 +102,6 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
break;
}
- e->pfcp_message = pfcp_message;
e->pfcp_xact_id = pfcp_xact ? pfcp_xact->id : OGS_INVALID_POOL_ID;
e->gtp_message = NULL;
diff --git a/src/sgwu/pfcp-path.c b/src/sgwu/pfcp-path.c
index 73def6adb..90093543a 100644
--- a/src/sgwu/pfcp-path.c
+++ b/src/sgwu/pfcp-path.c
@@ -61,8 +61,12 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from;
ogs_pfcp_node_t *node = NULL;
+ ogs_pfcp_message_t *message = NULL;
ogs_pfcp_header_t *h = NULL;
+ ogs_pfcp_status_e pfcp_status;;
+ ogs_pfcp_node_id_t node_id;
+
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
@@ -102,28 +106,105 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
e = sgwu_event_new(SGWU_EVT_SXA_MESSAGE);
ogs_assert(e);
- node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- ogs_error("No memory: ogs_pfcp_node_add() failed");
- ogs_pkbuf_free(e->pkbuf);
- sgwu_event_free(e);
- return;
- }
-
- node->sock = data;
- pfcp_node_fsm_init(node, false);
+ /*
+ * Issue #1911
+ *
+ * Because ogs_pfcp_message_t is over 80kb in size,
+ * it can cause stack overflow.
+ * To avoid this, the pfcp_message structure uses heap memory.
+ */
+ if ((message = ogs_pfcp_parse_msg(pkbuf)) == NULL) {
+ ogs_error("ogs_pfcp_parse_msg() failed");
+ ogs_pkbuf_free(pkbuf);
+ sgwu_event_free(e);
+ return;
}
+
+ pfcp_status = ogs_pfcp_extract_node_id(message, &node_id);
+ switch (pfcp_status) {
+ case OGS_PFCP_STATUS_SUCCESS:
+ case OGS_PFCP_STATUS_NODE_ID_NONE:
+ case OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT:
+ ogs_debug("ogs_pfcp_extract_node_id() "
+ "type [%d] pfcp_status [%d] node_id [%s] from %s",
+ message->h.type, pfcp_status,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ break;
+
+ case OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_FOUND:
+ case OGS_PFCP_ERROR_UNKNOWN_MESSAGE:
+ ogs_error("ogs_pfcp_extract_node_id() failed "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+
+ default:
+ ogs_error("Unexpected pfcp_status "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+
+ node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL, &from);
+ if (!node) {
+ if (message->h.type == OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE ||
+ message->h.type == OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE) {
+ ogs_assert(pfcp_status == OGS_PFCP_STATUS_SUCCESS);
+ node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list,
+ &node_id, &from);
+ if (!node) {
+ ogs_error("No memory: ogs_pfcp_node_add() failed");
+ goto cleanup;
+ }
+ ogs_debug("Added PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+
+ pfcp_node_fsm_init(node, false);
+
+ } else {
+ ogs_error("Cannot find PFCP-Node: type [%d] node_id %s from %s",
+ message->h.type,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+ } else {
+ ogs_debug("Found PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ ogs_expect(OGS_OK == ogs_pfcp_node_merge(
+ node,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL,
+ &from));
+ ogs_debug("Merged PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ }
+
e->pfcp_node = node;
e->pkbuf = pkbuf;
+ e->pfcp_message = message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
- ogs_pkbuf_free(e->pkbuf);
- sgwu_event_free(e);
+ goto cleanup;
}
+
+ return;
+
+cleanup:
+ ogs_pkbuf_free(pkbuf);
+ ogs_pfcp_message_free(message);
+ sgwu_event_free(e);
}
int sgwu_pfcp_open(void)
diff --git a/src/sgwu/pfcp-sm.c b/src/sgwu/pfcp-sm.c
index 9696cf4a7..130a79912 100644
--- a/src/sgwu/pfcp-sm.c
+++ b/src/sgwu/pfcp-sm.c
@@ -25,7 +25,6 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data);
void sgwu_pfcp_state_initial(ogs_fsm_t *s, sgwu_event_t *e)
{
- int rv;
ogs_pfcp_node_t *node = NULL;
ogs_assert(s);
@@ -36,10 +35,6 @@ void sgwu_pfcp_state_initial(ogs_fsm_t *s, sgwu_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- rv = ogs_pfcp_connect(
- ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
- ogs_assert(rv == OGS_OK);
-
node->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
sgwu_timer_no_heartbeat, node);
ogs_assert(node->t_no_heartbeat);
@@ -63,12 +58,9 @@ void sgwu_pfcp_state_final(ogs_fsm_t *s, sgwu_event_t *e)
void sgwu_pfcp_state_will_associate(ogs_fsm_t *s, sgwu_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
@@ -96,11 +88,8 @@ void sgwu_pfcp_state_will_associate(ogs_fsm_t *s, sgwu_event_t *e)
case SGWU_EVT_SXA_TIMER:
switch(e->timer_id) {
case SGWU_TIMER_ASSOCIATION:
- addr = node->sa_list;
- ogs_assert(addr);
-
- ogs_warn("Retry association with peer [%s]:%d failed",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("Retry association with peer failed %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
@@ -155,13 +144,10 @@ void sgwu_pfcp_state_will_associate(ogs_fsm_t *s, sgwu_event_t *e)
void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
sgwu_sess_t *sess = NULL;
ogs_assert(s);
@@ -171,14 +157,11 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
- ogs_info("PFCP associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_start(node->t_no_heartbeat,
ogs_local_conf()->time.message.pfcp.no_heartbeat_duration);
ogs_assert(OGS_OK ==
@@ -191,9 +174,8 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
}
break;
case OGS_FSM_EXIT_SIG:
- ogs_info("PFCP de-associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP de-associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_stop(node->t_no_heartbeat);
break;
case SGWU_EVT_SXA_MESSAGE:
@@ -263,16 +245,14 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
}
break;
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
- ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[REQ] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_up_handle_association_setup_request(node, xact,
&message->pfcp_association_setup_request);
break;
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
- ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[RSP] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_up_handle_association_setup_response(node, xact,
&message->pfcp_association_setup_response);
break;
@@ -318,8 +298,8 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
}
break;
case SGWU_EVT_SXA_NO_HEARTBEAT:
- ogs_warn("No Heartbeat from SGW-C [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("No Heartbeat from SGW-C %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
OGS_FSM_TRAN(s, sgwu_pfcp_state_will_associate);
break;
default:
diff --git a/src/sgwu/sgwu-sm.c b/src/sgwu/sgwu-sm.c
index 149070771..960430658 100644
--- a/src/sgwu/sgwu-sm.c
+++ b/src/sgwu/sgwu-sm.c
@@ -58,21 +58,11 @@ void sgwu_state_operational(ogs_fsm_t *s, sgwu_event_t *e)
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
node = e->pfcp_node;
ogs_assert(node);
-
- /*
- * Issue #1911
- *
- * Because ogs_pfcp_message_t is over 80kb in size,
- * it can cause stack overflow.
- * To avoid this, the pfcp_message structure uses heap memory.
- */
- if ((pfcp_message = ogs_pfcp_parse_msg(recvbuf)) == NULL) {
- ogs_error("ogs_pfcp_parse_msg() failed");
- ogs_pkbuf_free(recvbuf);
- break;
- }
+ ogs_assert(OGS_FSM_STATE(&node->sm));
rv = ogs_pfcp_xact_receive(node, &pfcp_message->h, &xact);
if (rv != OGS_OK) {
@@ -81,7 +71,6 @@ void sgwu_state_operational(ogs_fsm_t *s, sgwu_event_t *e)
break;
}
- e->pfcp_message = pfcp_message;
e->pfcp_xact_id = xact ? xact->id : OGS_INVALID_POOL_ID;
ogs_fsm_dispatch(&node->sm, e);
if (OGS_FSM_CHECK(&node->sm, sgwu_pfcp_state_exception)) {
diff --git a/src/sgwu/sxa-handler.c b/src/sgwu/sxa-handler.c
index 887dc73be..5153549ee 100644
--- a/src/sgwu/sxa-handler.c
+++ b/src/sgwu/sxa-handler.c
@@ -95,7 +95,17 @@ void sgwu_sxa_handle_session_establishment_request(
pdr = created_pdr[i];
ogs_assert(pdr);
- if (pdr->f_teid_len)
+ /*
+ * Only perform TEID restoration via swap when F-TEID.ch is false.
+ *
+ * When F-TEID.ch is false, it means the TEID has already been assigned, and
+ * the restoration process can safely perform the swap.
+ *
+ * If F-TEID.ch is true, it indicates that the UPF needs to assign
+ * a new TEID for the first time, so performing a swap is not appropriate
+ * in this case.
+ */
+ if (pdr->f_teid.ch == false && pdr->f_teid_len)
ogs_pfcp_pdr_swap_teid(pdr);
}
restoration_indication = true;
diff --git a/src/smf/binding.c b/src/smf/binding.c
index 139c12b5c..b76fcd742 100644
--- a/src/smf/binding.c
+++ b/src/smf/binding.c
@@ -206,15 +206,17 @@ void smf_bearer_binding(smf_sess_t *sess)
else
bearer->pgw_s5u_teid = ul_pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family ==
+ AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&bearer->pgw_s5u_addr,
- &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family ==
+ sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family ==
AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&bearer->pgw_s5u_addr6,
- &sess->pfcp_node->addr));
+ sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
@@ -599,19 +601,37 @@ void smf_qos_flow_binding(smf_sess_t *sess)
} else {
ogs_assert(strcmp(qos_flow->pcc_rule.id, pcc_rule->id) == 0);
- if ((pcc_rule->qos.mbr.downlink &&
- qos_flow->qos.mbr.downlink != pcc_rule->qos.mbr.downlink) ||
- (pcc_rule->qos.mbr.uplink &&
- qos_flow->qos.mbr.uplink != pcc_rule->qos.mbr.uplink) ||
- (pcc_rule->qos.gbr.downlink &&
- qos_flow->qos.gbr.downlink != pcc_rule->qos.gbr.downlink) ||
- (pcc_rule->qos.gbr.uplink &&
- qos_flow->qos.gbr.uplink != pcc_rule->qos.gbr.uplink)) {
- /* Update QoS parameter */
- memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
+ /*
+ * Check if any MBR/GBR value is non-zero. This indicates that
+ * the flow might require GBR/MBR-specific handling.
+ */
+ if (pcc_rule->qos.mbr.downlink || pcc_rule->qos.mbr.uplink ||
+ pcc_rule->qos.gbr.downlink || pcc_rule->qos.gbr.uplink) {
- /* Update Bearer Request encodes updated QoS parameter */
- qos_presence = true;
+ /*
+ * If new packet filters are being added, or if any MBR/GBR
+ * field differs from what is currently set, then we must
+ * update the QoS parameters.
+ */
+ if ((ogs_list_count(&qos_flow->pf_to_add_list) > 0) ||
+ (qos_flow->qos.mbr.downlink != pcc_rule->qos.mbr.downlink) ||
+ (qos_flow->qos.mbr.uplink != pcc_rule->qos.mbr.uplink) ||
+ (qos_flow->qos.gbr.downlink != pcc_rule->qos.gbr.downlink) ||
+ (qos_flow->qos.gbr.uplink != pcc_rule->qos.gbr.uplink)) {
+
+ /*
+ * Update the QoS parameters so that the GBR QoS Flow
+ * Information IE is properly encoded in the upcoming
+ * signaling (NGAP/PFCP) messages.
+ */
+ memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
+
+ /*
+ * Setting 'qos_presence' to true triggers encoding of
+ * the QoS IE in the subsequent Bearer Request message.
+ */
+ qos_presence = true;
+ }
}
}
diff --git a/src/smf/context.c b/src/smf/context.c
index 56212244a..93c8074ff 100644
--- a/src/smf/context.c
+++ b/src/smf/context.c
@@ -53,9 +53,11 @@ int smf_use_gy_iface(void)
{
switch (smf_self()->ctf_config.enabled) {
case SMF_CTF_ENABLED_AUTO:
- return ogs_diam_app_connected(OGS_DIAM_GY_APPLICATION_ID) ? 1 : 0;
+ return ogs_diam_is_relay_or_app_advertised(
+ OGS_DIAM_GY_APPLICATION_ID) ? 1 : 0;
case SMF_CTF_ENABLED_YES:
- return ogs_diam_app_connected(OGS_DIAM_GY_APPLICATION_ID) ? 1 : -1;
+ return ogs_diam_is_relay_or_app_advertised(
+ OGS_DIAM_GY_APPLICATION_ID) ? 1 : -1;
case SMF_CTF_ENABLED_NO:
return 0;
default:
@@ -1182,8 +1184,6 @@ static ogs_pfcp_node_t *selected_upf_node(
void smf_sess_select_upf(smf_sess_t *sess)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_assert(sess);
/*
@@ -1199,8 +1199,9 @@ void smf_sess_select_upf(smf_sess_t *sess)
selected_upf_node(ogs_pfcp_self()->pfcp_node, sess);
ogs_assert(ogs_pfcp_self()->pfcp_node);
OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->pfcp_node);
- ogs_debug("UE using UPF on IP[%s]",
- OGS_ADDR(&ogs_pfcp_self()->pfcp_node->addr, buf));
+ ogs_debug("UE using UPF on IP %s",
+ ogs_sockaddr_to_string_static(
+ ogs_pfcp_self()->pfcp_node->addr_list));
}
smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type)
@@ -1482,6 +1483,7 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
ogs_list_add(&smf_ue->sess_list, sess);
+ smf_metrics_inst_global_inc(SMF_METR_GLOB_GAUGE_PFCP_SESSIONS_ACTIVE);
stats_add_smf_session();
return sess;
@@ -1889,6 +1891,7 @@ void smf_sess_remove(smf_sess_t *sess)
smf_metrics_inst_global_dec(SMF_METR_GLOB_GAUGE_GTP2_SESSIONS_ACTIVE);
break;
}
+ smf_metrics_inst_global_dec(SMF_METR_GLOB_GAUGE_PFCP_SESSIONS_ACTIVE);
stats_remove_smf_session(sess);
ogs_pool_free(&smf_n4_seid_pool, sess->smf_n4_seid_node);
@@ -2369,14 +2372,16 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess)
else
sess->handover.local_dl_teid = pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK == ogs_copyaddrinfo(
&sess->handover.local_dl_addr,
- &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family ==
+ AF_INET6)
ogs_assert(OGS_OK == ogs_copyaddrinfo(
&sess->handover.local_dl_addr6,
- &sess->pfcp_node->addr));
+ sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
@@ -2453,6 +2458,7 @@ void smf_sess_create_cp_up_data_forwarding(smf_sess_t *sess)
ogs_pfcp_far_t *up2cp_far = NULL;
ogs_assert(sess);
+ ogs_assert(sess->session.name);
smf_sess_delete_cp_up_data_forwarding(sess);
@@ -2460,15 +2466,10 @@ void smf_sess_create_cp_up_data_forwarding(smf_sess_t *sess)
ogs_assert(cp2up_pdr);
sess->cp2up_pdr = cp2up_pdr;
-#if 0
- /*
- * DEPRECATED:
- * In PDR, no need to distinguish the Network Instance from CP to UP.
- */
- ogs_assert(sess->session.name);
- cp2up_pdr->apn = ogs_strdup(sess->session.name);
- ogs_assert(cp2up_pdr->apn);
-#endif
+ if (ogs_global_conf()->parameter.use_upg_vpp == true) {
+ cp2up_pdr->apn = ogs_strdup(sess->session.name);
+ ogs_assert(cp2up_pdr->apn);
+ }
cp2up_pdr->src_if = OGS_PFCP_INTERFACE_CP_FUNCTION;
@@ -2491,7 +2492,6 @@ void smf_sess_create_cp_up_data_forwarding(smf_sess_t *sess)
ogs_assert(up2cp_pdr);
sess->up2cp_pdr = up2cp_pdr;
- ogs_assert(sess->session.name);
up2cp_pdr->apn = ogs_strdup(sess->session.name);
ogs_assert(up2cp_pdr->apn);
@@ -2532,15 +2532,10 @@ void smf_sess_create_cp_up_data_forwarding(smf_sess_t *sess)
ogs_assert(up2cp_far);
sess->up2cp_far = up2cp_far;
- ogs_assert(sess->session.name);
-#if 0
- /*
- * DEPRECATED:
- * In FAR, no need to distinguish the Network Instance from CP to UP.
- */
- up2cp_far->apn = ogs_strdup(sess->session.name);
- ogs_assert(up2cp_far->apn);
-#endif
+ if (ogs_global_conf()->parameter.use_upg_vpp == true) {
+ up2cp_far->apn = ogs_strdup(sess->session.name);
+ ogs_assert(up2cp_far->apn);
+ }
up2cp_far->dst_if = OGS_PFCP_INTERFACE_CP_FUNCTION;
ogs_pfcp_pdr_associate_far(up2cp_pdr, up2cp_far);
@@ -3314,7 +3309,10 @@ int smf_pco_build(uint8_t *pco_buf, uint8_t *buffer, int length)
/* TODO */
break;
case OGS_PCO_ID_MS_SUPPORT_LOCAL_ADDR_TFT_INDICATOR:
- /* TODO */
+ smf.ids[smf.num_of_id].id = ue.ids[i].id;
+ smf.ids[smf.num_of_id].len = 0;
+ smf.ids[smf.num_of_id].data = 0;
+ smf.num_of_id++;
break;
case OGS_PCO_ID_P_CSCF_RE_SELECTION_SUPPORT:
/* TODO */
diff --git a/src/smf/context.h b/src/smf/context.h
index 48c57ca5a..2790d8c51 100644
--- a/src/smf/context.h
+++ b/src/smf/context.h
@@ -448,6 +448,7 @@ typedef struct smf_sess_s {
/* S_NSSAI */
ogs_s_nssai_t s_nssai;
ogs_s_nssai_t mapped_hplmn;
+ bool mapped_hplmn_presence;
/* PDN Configuration */
ogs_session_t session;
diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c
index 73001b347..c4c35b6ca 100644
--- a/src/smf/gn-handler.c
+++ b/src/smf/gn-handler.c
@@ -110,7 +110,7 @@ uint8_t smf_gn_handle_create_pdp_context_request(
cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING;
}
- if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
cause_value = OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
}
@@ -309,7 +309,7 @@ uint8_t smf_gn_handle_delete_pdp_context_request(
{
ogs_debug("Delete PDP Context Request");
- if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
}
diff --git a/src/smf/gsm-build.c b/src/smf/gsm-build.c
index 6024e2eab..a4531d942 100644
--- a/src/smf/gsm-build.c
+++ b/src/smf/gsm-build.c
@@ -170,7 +170,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
/* S-NSSAI */
pdu_session_establishment_accept->presencemask |=
OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_S_NSSAI_PRESENT;
- ogs_nas_build_s_nssai2(nas_s_nssai, &sess->s_nssai, &sess->mapped_hplmn);
+ ogs_nas_build_s_nssai2(nas_s_nssai, &sess->s_nssai,
+ (sess->mapped_hplmn_presence) ? &sess->mapped_hplmn : NULL);
/* QoS flow descriptions */
if (HOME_ROUTED_ROAMING_IN_VSMF(sess)) {
diff --git a/src/smf/gx-handler.c b/src/smf/gx-handler.c
index e9b6d043e..aba48bd99 100644
--- a/src/smf/gx-handler.c
+++ b/src/smf/gx-handler.c
@@ -210,14 +210,15 @@ uint32_t smf_gx_handle_cca_initial_request(
else
bearer->pgw_s5u_teid = ul_pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &bearer->pgw_s5u_addr, &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ &bearer->pgw_s5u_addr, sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &bearer->pgw_s5u_addr6, &sess->pfcp_node->addr));
+ &bearer->pgw_s5u_addr6, sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
diff --git a/src/smf/metrics.c b/src/smf/metrics.c
index dd8cf3370..626fd9099 100644
--- a/src/smf/metrics.c
+++ b/src/smf/metrics.c
@@ -126,6 +126,16 @@ smf_metrics_spec_def_t smf_metrics_spec_def_global[_SMF_METR_GLOB_MAX] = {
.name = "gtp_peers_active",
.description = "Active GTP peers",
},
+[SMF_METR_GLOB_GAUGE_PFCP_SESSIONS_ACTIVE] = {
+ .type = OGS_METRICS_METRIC_TYPE_GAUGE,
+ .name = "pfcp_sessions_active",
+ .description = "Active PFCP Sessions",
+},
+[SMF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE] = {
+ .type = OGS_METRICS_METRIC_TYPE_GAUGE,
+ .name = "pfcp_peers_active",
+ .description = "Active PFCP peers",
+},
};
int smf_metrics_init_inst_global(void)
{
diff --git a/src/smf/metrics.h b/src/smf/metrics.h
index 8a2209e0c..3cb4991df 100644
--- a/src/smf/metrics.h
+++ b/src/smf/metrics.h
@@ -24,6 +24,8 @@ typedef enum smf_metric_type_global_s {
SMF_METR_GLOB_GAUGE_GTP1_PDPCTXS_ACTIVE,
SMF_METR_GLOB_GAUGE_GTP2_SESSIONS_ACTIVE,
SMF_METR_GLOB_GAUGE_GTP_PEERS_ACTIVE,
+ SMF_METR_GLOB_GAUGE_PFCP_SESSIONS_ACTIVE,
+ SMF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE,
_SMF_METR_GLOB_MAX,
} smf_metric_type_global_t;
extern ogs_metrics_inst_t *smf_metrics_inst_global[_SMF_METR_GLOB_MAX];
diff --git a/src/smf/npcf-handler.c b/src/smf/npcf-handler.c
index ef72c6523..d393a1d18 100644
--- a/src/smf/npcf-handler.c
+++ b/src/smf/npcf-handler.c
@@ -345,7 +345,7 @@ bool smf_npcf_smpolicycontrol_handle_create(
ogs_error("[%s:%d] Invalid URI [%s]",
smf_ue->supi, sess->psi, header.uri);
ogs_sbi_header_free(&header);
- return OGS_ERROR;
+ return false;
}
client = ogs_sbi_client_find(scheme, fqdn, fqdn_port, addr, addr6);
@@ -361,7 +361,7 @@ bool smf_npcf_smpolicycontrol_handle_create(
ogs_freeaddrinfo(addr);
ogs_freeaddrinfo(addr6);
- return OGS_ERROR;
+ return false;
}
}
@@ -524,16 +524,11 @@ bool smf_npcf_smpolicycontrol_handle_create(
&dl_pdr->ue_ip_addr, &dl_pdr->ue_ip_addr_len));
dl_pdr->ue_ip_addr.sd = OGS_PFCP_UE_IP_DST;
-#if 0
- /* DEPRECATED:
- *
- * The UE IP Address is unnecessary in the PDI of the UL PDR
- * because the PDR can be found using the TEID.
- */
- ogs_assert(OGS_OK ==
- ogs_pfcp_paa_to_ue_ip_addr(&sess->paa,
- &ul_pdr->ue_ip_addr, &ul_pdr->ue_ip_addr_len));
-#endif
+ if (ogs_global_conf()->parameter.use_upg_vpp == true) {
+ ogs_assert(OGS_OK ==
+ ogs_pfcp_paa_to_ue_ip_addr(&sess->paa,
+ &ul_pdr->ue_ip_addr, &ul_pdr->ue_ip_addr_len));
+ }
if (sess->session.ipv4_framed_routes &&
sess->pfcp_node->up_function_features.frrt) {
@@ -664,14 +659,15 @@ bool smf_npcf_smpolicycontrol_handle_create(
else
sess->local_ul_teid = ul_pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_ul_addr, &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ &sess->local_ul_addr, sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_ul_addr6, &sess->pfcp_node->addr));
+ &sess->local_ul_addr6, sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c
index ac555c74e..777bd7935 100644
--- a/src/smf/nsmf-handler.c
+++ b/src/smf/nsmf-handler.c
@@ -290,6 +290,7 @@ bool smf_nsmf_handle_create_sm_context(
sess->s_nssai.sst = sNssai->sst;
sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sNssai->sd);
if (SmContextCreateData->hplmn_snssai) {
+ sess->mapped_hplmn_presence = true;
sess->mapped_hplmn.sst = SmContextCreateData->hplmn_snssai->sst;
sess->mapped_hplmn.sd = ogs_s_nssai_sd_from_string(
SmContextCreateData->hplmn_snssai->sd);
@@ -532,14 +533,15 @@ bool smf_nsmf_handle_create_sm_context(
else
sess->local_dl_teid = dl_pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_dl_addr, &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ &sess->local_dl_addr, sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_dl_addr6, &sess->pfcp_node->addr));
+ &sess->local_dl_addr6, sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
@@ -565,14 +567,15 @@ bool smf_nsmf_handle_create_sm_context(
else
sess->local_ul_teid = ul_pdr->teid;
} else {
- if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
+ ogs_assert(sess->pfcp_node->addr_list);
+ if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_ul_addr, &sess->pfcp_node->addr));
- else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
+ &sess->local_ul_addr, sess->pfcp_node->addr_list));
+ else if (sess->pfcp_node->addr_list->ogs_sa_family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(
- &sess->local_ul_addr6, &sess->pfcp_node->addr));
+ &sess->local_ul_addr6, sess->pfcp_node->addr_list));
else
ogs_assert_if_reached();
@@ -2126,5 +2129,5 @@ cleanup:
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
- return OGS_OK;
+ return true;
}
diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c
index 8ed2f143b..460b09fb6 100644
--- a/src/smf/pfcp-path.c
+++ b/src/smf/pfcp-path.c
@@ -101,8 +101,12 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from;
ogs_pfcp_node_t *node = NULL;
+ ogs_pfcp_message_t *message = NULL;
ogs_pfcp_header_t *h = NULL;
+ ogs_pfcp_status_e pfcp_status;;
+ ogs_pfcp_node_id_t node_id;
+
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
@@ -142,28 +146,105 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
e = smf_event_new(SMF_EVT_N4_MESSAGE);
ogs_assert(e);
- node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- ogs_error("No memory: ogs_pfcp_node_add() failed");
- ogs_pkbuf_free(e->pkbuf);
- ogs_event_free(e);
- return;
- }
-
- node->sock = data;
- pfcp_node_fsm_init(node, false);
+ /*
+ * Issue #1911
+ *
+ * Because ogs_pfcp_message_t is over 80kb in size,
+ * it can cause stack overflow.
+ * To avoid this, the pfcp_message structure uses heap memory.
+ */
+ if ((message = ogs_pfcp_parse_msg(pkbuf)) == NULL) {
+ ogs_error("ogs_pfcp_parse_msg() failed");
+ ogs_pkbuf_free(pkbuf);
+ ogs_event_free(e);
+ return;
}
+
+ pfcp_status = ogs_pfcp_extract_node_id(message, &node_id);
+ switch (pfcp_status) {
+ case OGS_PFCP_STATUS_SUCCESS:
+ case OGS_PFCP_STATUS_NODE_ID_NONE:
+ case OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT:
+ ogs_debug("ogs_pfcp_extract_node_id() "
+ "type [%d] pfcp_status [%d] node_id [%s] from %s",
+ message->h.type, pfcp_status,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ break;
+
+ case OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_FOUND:
+ case OGS_PFCP_ERROR_UNKNOWN_MESSAGE:
+ ogs_error("ogs_pfcp_extract_node_id() failed "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+
+ default:
+ ogs_error("Unexpected pfcp_status "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+
+ node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL, &from);
+ if (!node) {
+ if (message->h.type == OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE ||
+ message->h.type == OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE) {
+ ogs_assert(pfcp_status == OGS_PFCP_STATUS_SUCCESS);
+ node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list,
+ &node_id, &from);
+ if (!node) {
+ ogs_error("No memory: ogs_pfcp_node_add() failed");
+ goto cleanup;
+ }
+ ogs_debug("Added PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+
+ pfcp_node_fsm_init(node, false);
+
+ } else {
+ ogs_error("Cannot find PFCP-Node: type [%d] node_id %s from %s",
+ message->h.type,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+ } else {
+ ogs_debug("Found PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ ogs_expect(OGS_OK == ogs_pfcp_node_merge(
+ node,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL,
+ &from));
+ ogs_debug("Merged PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ }
+
e->pfcp_node = node;
e->pkbuf = pkbuf;
+ e->pfcp_message = message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
- ogs_pkbuf_free(e->pkbuf);
- ogs_event_free(e);
+ goto cleanup;
}
+
+ return;
+
+cleanup:
+ ogs_pkbuf_free(pkbuf);
+ ogs_pfcp_message_free(message);
+ ogs_event_free(e);
}
int smf_pfcp_open(void)
diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c
index 6cb176441..d7d313441 100644
--- a/src/smf/pfcp-sm.c
+++ b/src/smf/pfcp-sm.c
@@ -28,7 +28,6 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data);
void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
- int rv;
ogs_pfcp_node_t *node = NULL;
ogs_assert(s);
@@ -39,10 +38,6 @@ void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- rv = ogs_pfcp_connect(
- ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
- ogs_assert(rv == OGS_OK);
-
node->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
smf_timer_pfcp_no_heartbeat, node);
ogs_assert(node->t_no_heartbeat);
@@ -66,13 +61,10 @@ void smf_pfcp_state_final(ogs_fsm_t *s, smf_event_t *e)
void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
smf_sess_t *sess;
ogs_assert(s);
@@ -82,8 +74,6 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
@@ -107,8 +97,8 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- ogs_warn("Retry association with peer [%s]:%d failed",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("Retry association with peer failed %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
@@ -179,13 +169,10 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
smf_sess_t *sess = NULL;
ogs_assert(s);
@@ -195,14 +182,11 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
- ogs_info("PFCP associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_start(node->t_no_heartbeat,
ogs_local_conf()->time.message.pfcp.no_heartbeat_duration);
ogs_assert(OGS_OK ==
@@ -213,12 +197,15 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
node->restoration_required = false;
ogs_error("PFCP restoration");
}
+
+ smf_metrics_inst_global_inc(SMF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE);
break;
case OGS_FSM_EXIT_SIG:
- ogs_info("PFCP de-associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP de-associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_stop(node->t_no_heartbeat);
+
+ smf_metrics_inst_global_dec(SMF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE);
break;
case SMF_EVT_N4_MESSAGE:
message = e->pfcp_message;
@@ -296,16 +283,14 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
}
break;
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
- ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[REQ] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_cp_handle_association_setup_request(node, xact,
&message->pfcp_association_setup_request);
break;
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
- ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[RSP] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_cp_handle_association_setup_response(node, xact,
&message->pfcp_association_setup_response);
break;
@@ -421,8 +406,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
}
break;
case SMF_EVT_N4_NO_HEARTBEAT:
- ogs_warn("No Heartbeat from UPF [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("No Heartbeat from UPF %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
/*
* reselect_upf() should not be executed on node_timeout
diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c
index d37683c73..d03dfa9c7 100644
--- a/src/smf/s5c-handler.c
+++ b/src/smf/s5c-handler.c
@@ -155,7 +155,7 @@ uint8_t smf_s5c_handle_create_session_request(
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
}
- if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
cause_value = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
@@ -172,7 +172,7 @@ uint8_t smf_s5c_handle_create_session_request(
}
break;
case OGS_GTP2_RAT_TYPE_WLAN:
- if (!ogs_diam_app_connected(OGS_DIAM_S6B_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_S6B_APPLICATION_ID)) {
ogs_error("No S6b Diameter Peer");
cause_value = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
@@ -485,13 +485,13 @@ uint8_t smf_s5c_handle_delete_session_request(
ogs_assert(xact);
ogs_assert(req);
- if (!ogs_diam_app_connected(OGS_DIAM_GX_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_GX_APPLICATION_ID)) {
ogs_error("No Gx Diameter Peer");
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
- if (!ogs_diam_app_connected(OGS_DIAM_S6B_APPLICATION_ID)) {
+ if (!ogs_diam_is_relay_or_app_advertised(OGS_DIAM_S6B_APPLICATION_ID)) {
ogs_error("No S6b Diameter Peer");
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c
index b8f4327ed..33c07767d 100644
--- a/src/smf/smf-sm.c
+++ b/src/smf/smf-sm.c
@@ -408,23 +408,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
pfcp_node = e->pfcp_node;
ogs_assert(pfcp_node);
ogs_assert(OGS_FSM_STATE(&pfcp_node->sm));
- /*
- * Issue #1911
- *
- * Because ogs_pfcp_message_t is over 80kb in size,
- * it can cause stack overflow.
- * To avoid this, the pfcp_message structure uses heap memory.
- */
- if ((pfcp_message = ogs_pfcp_parse_msg(recvbuf)) == NULL) {
- ogs_error("ogs_pfcp_parse_msg() failed");
- ogs_pkbuf_free(recvbuf);
- break;
- }
-
rv = ogs_pfcp_xact_receive(pfcp_node, &pfcp_message->h, &pfcp_xact);
if (rv != OGS_OK) {
ogs_pkbuf_free(recvbuf);
@@ -432,7 +421,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
}
- e->pfcp_message = pfcp_message;
e->pfcp_xact_id = pfcp_xact ? pfcp_xact->id : OGS_INVALID_POOL_ID;
e->gtp2_message = NULL;
diff --git a/src/udm/nudm-handler.c b/src/udm/nudm-handler.c
index 8ce08e7fa..52101b4f0 100644
--- a/src/udm/nudm-handler.c
+++ b/src/udm/nudm-handler.c
@@ -558,7 +558,7 @@ bool udm_nudm_uecm_handle_smf_registration(
return false;
}
- if (!SmfRegistration->single_nssai || !SmfRegistration->single_nssai->sst) {
+ if (!SmfRegistration->single_nssai) {
ogs_error("[%s:%d] No singleNssai", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
diff --git a/src/udm/nudr-handler.c b/src/udm/nudr-handler.c
index a6050bda6..027482048 100644
--- a/src/udm/nudr-handler.c
+++ b/src/udm/nudr-handler.c
@@ -808,8 +808,7 @@ bool udm_nudr_dr_handle_smf_registration(
return false;
}
- if (!SmfRegistration->single_nssai ||
- !SmfRegistration->single_nssai->sst) {
+ if (!SmfRegistration->single_nssai) {
ogs_error("[%s:%d] No singleNssai", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
diff --git a/src/upf/context.c b/src/upf/context.c
index 7c286fa82..84b1d3057 100644
--- a/src/upf/context.c
+++ b/src/upf/context.c
@@ -682,9 +682,12 @@ uint8_t upf_sess_set_ue_ipv6_framed_routes(upf_sess_t *sess,
void upf_sess_urr_acc_add(upf_sess_t *sess, ogs_pfcp_urr_t *urr, size_t size, bool is_uplink)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
uint64_t vol;
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
+
/* Increment total & ul octets + pkts */
urr_acc->total_octets += size;
urr_acc->total_pkts++;
@@ -722,10 +725,13 @@ void upf_sess_urr_acc_add(upf_sess_t *sess, ogs_pfcp_urr_t *urr, size_t size, bo
void upf_sess_urr_acc_fill_usage_report(upf_sess_t *sess, const ogs_pfcp_urr_t *urr,
ogs_pfcp_user_plane_report_t *report, unsigned int idx)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
ogs_time_t last_report_timestamp;
ogs_time_t now;
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
+
now = ogs_time_now(); /* we need UTC for start_time and end_time */
if (urr_acc->last_report.timestamp)
@@ -780,7 +786,11 @@ void upf_sess_urr_acc_fill_usage_report(upf_sess_t *sess, const ogs_pfcp_urr_t *
void upf_sess_urr_acc_snapshot(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
+
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
+
urr_acc->last_report.total_octets = urr_acc->total_octets;
urr_acc->last_report.dl_octets = urr_acc->dl_octets;
urr_acc->last_report.ul_octets = urr_acc->ul_octets;
@@ -816,7 +826,10 @@ static void upf_sess_urr_acc_timers_cb(void *data)
static void upf_sess_urr_acc_validity_time_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
+
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
ogs_debug("Installing URR Quota Validity Time timer");
urr_acc->reporting_enabled = true;
@@ -829,7 +842,10 @@ static void upf_sess_urr_acc_validity_time_setup(upf_sess_t *sess, ogs_pfcp_urr_
static void upf_sess_urr_acc_time_quota_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
+
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
ogs_debug("Installing URR Time Quota timer");
urr_acc->reporting_enabled = true;
@@ -841,7 +857,10 @@ static void upf_sess_urr_acc_time_quota_setup(upf_sess_t *sess, ogs_pfcp_urr_t *
static void upf_sess_urr_acc_time_threshold_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
+
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
ogs_debug("Installing URR Time Threshold timer");
urr_acc->reporting_enabled = true;
@@ -854,7 +873,11 @@ static void upf_sess_urr_acc_time_threshold_setup(upf_sess_t *sess, ogs_pfcp_urr
void upf_sess_urr_acc_timers_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
{
- upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
+ upf_sess_urr_acc_t *urr_acc = NULL;
+
+ ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
+ urr_acc = &sess->urr_acc[urr->id-1];
+
urr_acc->time_start = ogs_time_ntp32_now();
if (urr->rep_triggers.quota_validity_time && urr->quota_validity_time > 0)
upf_sess_urr_acc_validity_time_setup(sess, urr);
diff --git a/src/upf/metrics.c b/src/upf/metrics.c
index 5f280404f..1a0ca1f0d 100644
--- a/src/upf/metrics.c
+++ b/src/upf/metrics.c
@@ -82,6 +82,11 @@ upf_metrics_spec_def_t upf_metrics_spec_def_global[_UPF_METR_GLOB_MAX] = {
.name = "fivegs_upffunction_upf_sessionnbr",
.description = "Active Sessions",
},
+[UPF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE] = {
+ .type = OGS_METRICS_METRIC_TYPE_GAUGE,
+ .name = "pfcp_peers_active",
+ .description = "Active PFCP peers",
+},
};
int upf_metrics_init_inst_global(void)
{
diff --git a/src/upf/metrics.h b/src/upf/metrics.h
index d4e930218..5df082bf0 100644
--- a/src/upf/metrics.h
+++ b/src/upf/metrics.h
@@ -15,6 +15,7 @@ typedef enum upf_metric_type_global_s {
UPF_METR_GLOB_CTR_SM_N4SESSIONREPORT,
UPF_METR_GLOB_CTR_SM_N4SESSIONREPORTSUCC,
UPF_METR_GLOB_GAUGE_UPF_SESSIONNBR,
+ UPF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE,
_UPF_METR_GLOB_MAX,
} upf_metric_type_global_t;
extern ogs_metrics_inst_t *upf_metrics_inst_global[_UPF_METR_GLOB_MAX];
diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c
index 9e4690da2..18d7e836b 100644
--- a/src/upf/n4-handler.c
+++ b/src/upf/n4-handler.c
@@ -152,7 +152,17 @@ void upf_n4_handle_session_establishment_request(
pdr = created_pdr[i];
ogs_assert(pdr);
- if (pdr->f_teid_len)
+ /*
+ * Only perform TEID restoration via swap when F-TEID.ch is false.
+ *
+ * When F-TEID.ch is false, it means the TEID has already been assigned, and
+ * the restoration process can safely perform the swap.
+ *
+ * If F-TEID.ch is true, it indicates that the UPF needs to assign
+ * a new TEID for the first time, so performing a swap is not appropriate
+ * in this case.
+ */
+ if (pdr->f_teid.ch == false && pdr->f_teid_len)
ogs_pfcp_pdr_swap_teid(pdr);
}
restoration_indication = true;
diff --git a/src/upf/pfcp-path.c b/src/upf/pfcp-path.c
index ea4591dce..bd5c5d03a 100644
--- a/src/upf/pfcp-path.c
+++ b/src/upf/pfcp-path.c
@@ -64,8 +64,12 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from;
ogs_pfcp_node_t *node = NULL;
+ ogs_pfcp_message_t *message = NULL;
ogs_pfcp_header_t *h = NULL;
+ ogs_pfcp_status_e pfcp_status;;
+ ogs_pfcp_node_id_t node_id;
+
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
@@ -105,28 +109,105 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
e = upf_event_new(UPF_EVT_N4_MESSAGE);
ogs_assert(e);
- node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list, &from);
- if (!node) {
- ogs_error("No memory: ogs_pfcp_node_add() failed");
- ogs_pkbuf_free(e->pkbuf);
- upf_event_free(e);
- return;
- }
-
- node->sock = data;
- pfcp_node_fsm_init(node, false);
+ /*
+ * Issue #1911
+ *
+ * Because ogs_pfcp_message_t is over 80kb in size,
+ * it can cause stack overflow.
+ * To avoid this, the pfcp_message structure uses heap memory.
+ */
+ if ((message = ogs_pfcp_parse_msg(pkbuf)) == NULL) {
+ ogs_error("ogs_pfcp_parse_msg() failed");
+ ogs_pkbuf_free(pkbuf);
+ upf_event_free(e);
+ return;
}
+
+ pfcp_status = ogs_pfcp_extract_node_id(message, &node_id);
+ switch (pfcp_status) {
+ case OGS_PFCP_STATUS_SUCCESS:
+ case OGS_PFCP_STATUS_NODE_ID_NONE:
+ case OGS_PFCP_STATUS_NODE_ID_OPTIONAL_ABSENT:
+ ogs_debug("ogs_pfcp_extract_node_id() "
+ "type [%d] pfcp_status [%d] node_id [%s] from %s",
+ message->h.type, pfcp_status,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ break;
+
+ case OGS_PFCP_ERROR_SEMANTIC_INCORRECT_MESSAGE:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_PRESENT:
+ case OGS_PFCP_ERROR_NODE_ID_NOT_FOUND:
+ case OGS_PFCP_ERROR_UNKNOWN_MESSAGE:
+ ogs_error("ogs_pfcp_extract_node_id() failed "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+
+ default:
+ ogs_error("Unexpected pfcp_status "
+ "type [%d] pfcp_status [%d] from %s",
+ message->h.type, pfcp_status,
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+
+ node = ogs_pfcp_node_find(&ogs_pfcp_self()->pfcp_peer_list,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL, &from);
+ if (!node) {
+ if (message->h.type == OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE ||
+ message->h.type == OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE) {
+ ogs_assert(pfcp_status == OGS_PFCP_STATUS_SUCCESS);
+ node = ogs_pfcp_node_add(&ogs_pfcp_self()->pfcp_peer_list,
+ &node_id, &from);
+ if (!node) {
+ ogs_error("No memory: ogs_pfcp_node_add() failed");
+ goto cleanup;
+ }
+ ogs_debug("Added PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+
+ pfcp_node_fsm_init(node, false);
+
+ } else {
+ ogs_error("Cannot find PFCP-Node: type [%d] node_id %s from %s",
+ message->h.type,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ?
+ ogs_pfcp_node_id_to_string_static(&node_id) :
+ "NULL",
+ ogs_sockaddr_to_string_static(&from));
+ goto cleanup;
+ }
+ } else {
+ ogs_debug("Found PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ ogs_expect(OGS_OK == ogs_pfcp_node_merge(
+ node,
+ pfcp_status == OGS_PFCP_STATUS_SUCCESS ? &node_id : NULL,
+ &from));
+ ogs_debug("Merged PFCP-Node: addr_list %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
+ }
+
e->pfcp_node = node;
e->pkbuf = pkbuf;
+ e->pfcp_message = message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
- ogs_pkbuf_free(e->pkbuf);
- upf_event_free(e);
+ goto cleanup;
}
+
+ return;
+
+cleanup:
+ ogs_pkbuf_free(pkbuf);
+ ogs_pfcp_message_free(message);
+ upf_event_free(e);
}
int upf_pfcp_open(void)
diff --git a/src/upf/pfcp-sm.c b/src/upf/pfcp-sm.c
index 7a1f74b94..27499ef44 100644
--- a/src/upf/pfcp-sm.c
+++ b/src/upf/pfcp-sm.c
@@ -30,7 +30,6 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data);
void upf_pfcp_state_initial(ogs_fsm_t *s, upf_event_t *e)
{
- int rv;
ogs_pfcp_node_t *node = NULL;
ogs_assert(s);
@@ -41,10 +40,6 @@ void upf_pfcp_state_initial(ogs_fsm_t *s, upf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- rv = ogs_pfcp_connect(
- ogs_pfcp_self()->pfcp_sock, ogs_pfcp_self()->pfcp_sock6, node);
- ogs_assert(rv == OGS_OK);
-
node->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
upf_timer_no_heartbeat, node);
ogs_assert(node->t_no_heartbeat);
@@ -68,12 +63,9 @@ void upf_pfcp_state_final(ogs_fsm_t *s, upf_event_t *e)
void upf_pfcp_state_will_associate(ogs_fsm_t *s, upf_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
@@ -101,11 +93,8 @@ void upf_pfcp_state_will_associate(ogs_fsm_t *s, upf_event_t *e)
case UPF_EVT_N4_TIMER:
switch(e->timer_id) {
case UPF_TIMER_ASSOCIATION:
- addr = node->sa_list;
- ogs_assert(addr);
-
- ogs_warn("Retry association with peer [%s]:%d failed",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("Retry association with peer failed %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_assert(node->t_association);
ogs_timer_start(node->t_association,
@@ -160,13 +149,10 @@ void upf_pfcp_state_will_associate(ogs_fsm_t *s, upf_event_t *e)
void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
{
- char buf[OGS_ADDRSTRLEN];
-
ogs_pfcp_node_t *node = NULL;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_message_t *message = NULL;
- ogs_sockaddr_t *addr = NULL;
upf_sess_t *sess = NULL;
ogs_assert(s);
@@ -176,14 +162,11 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
node = e->pfcp_node;
ogs_assert(node);
- addr = node->sa_list;
- ogs_assert(addr);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
- ogs_info("PFCP associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_start(node->t_no_heartbeat,
ogs_local_conf()->time.message.pfcp.no_heartbeat_duration);
ogs_assert(OGS_OK ==
@@ -194,12 +177,15 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
node->restoration_required = false;
ogs_error("PFCP restoration");
}
+
+ upf_metrics_inst_global_inc(UPF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE);
break;
case OGS_FSM_EXIT_SIG:
- ogs_info("PFCP de-associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_info("PFCP de-associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_timer_stop(node->t_no_heartbeat);
+
+ upf_metrics_inst_global_dec(UPF_METR_GLOB_GAUGE_PFCP_PEERS_ACTIVE);
break;
case UPF_EVT_N4_MESSAGE:
message = e->pfcp_message;
@@ -267,16 +253,14 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
}
break;
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
- ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[REQ] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_up_handle_association_setup_request(node, xact,
&message->pfcp_association_setup_request);
break;
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
- ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
- OGS_ADDR(&node->addr, buf),
- OGS_PORT(&node->addr));
+ ogs_warn("PFCP[RSP] has already been associated %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
ogs_pfcp_up_handle_association_setup_response(node, xact,
&message->pfcp_association_setup_response);
break;
@@ -322,8 +306,8 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
}
break;
case UPF_EVT_N4_NO_HEARTBEAT:
- ogs_warn("No Heartbeat from SMF [%s]:%d",
- OGS_ADDR(addr, buf), OGS_PORT(addr));
+ ogs_warn("No Heartbeat from SMF %s",
+ ogs_sockaddr_to_string_static(node->addr_list));
OGS_FSM_TRAN(s, upf_pfcp_state_will_associate);
break;
default:
diff --git a/src/upf/upf-sm.c b/src/upf/upf-sm.c
index a4e842546..df85d21d7 100644
--- a/src/upf/upf-sm.c
+++ b/src/upf/upf-sm.c
@@ -63,21 +63,11 @@ void upf_state_operational(ogs_fsm_t *s, upf_event_t *e)
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
+ pfcp_message = e->pfcp_message;
+ ogs_assert(pfcp_message);
node = e->pfcp_node;
ogs_assert(node);
-
- /*
- * Issue #1911
- *
- * Because ogs_pfcp_message_t is over 80kb in size,
- * it can cause stack overflow.
- * To avoid this, the pfcp_message structure uses heap memory.
- */
- if ((pfcp_message = ogs_pfcp_parse_msg(recvbuf)) == NULL) {
- ogs_error("ogs_pfcp_parse_msg() failed");
- ogs_pkbuf_free(recvbuf);
- break;
- }
+ ogs_assert(OGS_FSM_STATE(&node->sm));
rv = ogs_pfcp_xact_receive(node, &pfcp_message->h, &xact);
if (rv != OGS_OK) {
@@ -86,7 +76,6 @@ void upf_state_operational(ogs_fsm_t *s, upf_event_t *e)
break;
}
- e->pfcp_message = pfcp_message;
e->pfcp_xact_id = xact ? xact->id : OGS_INVALID_POOL_ID;
ogs_fsm_dispatch(&node->sm, e);
if (OGS_FSM_CHECK(&node->sm, upf_pfcp_state_exception)) {
diff --git a/tests/af/npcf-build.c b/tests/af/npcf-build.c
index 688a72f66..136106aff 100644
--- a/tests/af/npcf-build.c
+++ b/tests/af/npcf-build.c
@@ -115,11 +115,9 @@ ogs_sbi_request_t *af_npcf_policyauthorization_build_create(
AscReqData.ev_subsc = &evSubsc;
memset(&sNssai, 0, sizeof(sNssai));
- if (sess->s_nssai.sst) {
- sNssai.sst = sess->s_nssai.sst;
- sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
- AscReqData.slice_info = &sNssai;
- }
+ sNssai.sst = sess->s_nssai.sst;
+ sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
+ AscReqData.slice_info = &sNssai;
AscReqData.spon_status = OpenAPI_sponsoring_status_SPONSOR_DISABLED;
@@ -709,11 +707,10 @@ ogs_sbi_request_t *af_npcf_policyauthorization_build_create_video(
AscReqData.ev_subsc = &evSubsc;
memset(&sNssai, 0, sizeof(sNssai));
- if (sess->s_nssai.sst) {
- sNssai.sst = sess->s_nssai.sst;
- sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
- AscReqData.slice_info = &sNssai;
- }
+
+ sNssai.sst = sess->s_nssai.sst;
+ sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
+ AscReqData.slice_info = &sNssai;
AscReqData.spon_status = OpenAPI_sponsoring_status_SPONSOR_DISABLED;
diff --git a/tests/common/context.c b/tests/common/context.c
index a584dcd7e..cc879de0c 100644
--- a/tests/common/context.c
+++ b/tests/common/context.c
@@ -1174,6 +1174,7 @@ test_ue_t *test_ue_add_by_suci(
s_nssai->sst = 0;
s_nssai->sd.v = OGS_S_NSSAI_NO_SD_VALUE;
+ s_nssai->mapped_hplmn_sst_presence = false;
s_nssai->mapped_hplmn_sst = 0;
s_nssai->mapped_hplmn_sd.v = OGS_S_NSSAI_NO_SD_VALUE;
diff --git a/tests/common/sctp.c b/tests/common/sctp.c
index a08bcca7c..575d8ca08 100644
--- a/tests/common/sctp.c
+++ b/tests/common/sctp.c
@@ -54,7 +54,7 @@ ogs_socknode_t *testsctp_client(const char *ipstr, int port)
node = ogs_socknode_new(addr);
ogs_assert(node);
- sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
+ sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL, NULL);
ogs_assert(sock);
node->sock = sock;
@@ -82,7 +82,7 @@ ogs_socknode_t *tests1ap_client(int family)
node = ogs_socknode_new(addr);
ogs_assert(node);
- sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
+ sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL, NULL);
ogs_assert(sock);
node->sock = sock;
@@ -121,7 +121,7 @@ ogs_socknode_t *testngap_client(int index, int family)
node = ogs_socknode_new(addr);
ogs_assert(node);
- sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
+ sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL, NULL);
ogs_assert(sock);
node->sock = sock;
diff --git a/tests/handover/5gc-n2-test.c b/tests/handover/5gc-n2-test.c
index 8b7f4323c..b8f355e3c 100644
--- a/tests/handover/5gc-n2-test.c
+++ b/tests/handover/5gc-n2-test.c
@@ -515,7 +515,7 @@ static void direct_complete_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, gtpu2);
/* NG-Setup Reqeust/Response for Source gNB */
- sendbuf = testngap_build_ng_setup_request(0x4000, 28);
+ sendbuf = testngap_build_ng_setup_request(0, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -769,7 +769,7 @@ static void direct_complete_func(abts_case *tc, void *data)
/* Send UplinkRANConfigurationTransfer */
sendbuf = testngap_build_uplink_ran_configuration_transfer(
- 0x4000, 28, 0x4001, 28);
+ 0, 28, 0x4001, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -781,7 +781,7 @@ static void direct_complete_func(abts_case *tc, void *data)
/* Send UplinkRANConfigurationTransfer */
sendbuf = testngap_build_uplink_ran_configuration_transfer(
- 0x4001, 28, 0x4000, 28);
+ 0x4001, 28, 0, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -911,7 +911,7 @@ static void direct_complete_func(abts_case *tc, void *data)
/* Send HandoverRequired */
sendbuf = testngap_build_handover_required(
test_ue, NGAP_HandoverType_intra5gs,
- 0x4000, 28,
+ 0, 28,
NGAP_Cause_PR_radioNetwork,
NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason,
true);
diff --git a/tests/sctp/sctp-test.c b/tests/sctp/sctp-test.c
index 288e06b44..436185293 100644
--- a/tests/sctp/sctp-test.c
+++ b/tests/sctp/sctp-test.c
@@ -53,7 +53,7 @@ static void test1_func(abts_case *tc, void *data)
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
- rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST1_PORT2, AI_PASSIVE);
+ rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST1_PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
@@ -77,7 +77,7 @@ static void test2_main(void *data)
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST2_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
- sctp = ogs_sctp_client(SOCK_SEQPACKET, addr, NULL);
+ sctp = ogs_sctp_client(SOCK_SEQPACKET, addr, NULL, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
size = ogs_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
@@ -192,7 +192,7 @@ static void test4_main(void *data)
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST4_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
- sctp = ogs_sctp_client(SOCK_STREAM, addr, NULL);
+ sctp = ogs_sctp_client(SOCK_STREAM, addr, NULL, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
size = ogs_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0);
diff --git a/tests/slice/same-dnn-test.c b/tests/slice/same-dnn-test.c
index 64263bf6c..f2f90ddb0 100644
--- a/tests/slice/same-dnn-test.c
+++ b/tests/slice/same-dnn-test.c
@@ -426,6 +426,8 @@ static void test2_func(abts_case *tc, void *data)
sst = 2;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
sd.v = OGS_S_NSSAI_NO_SD_VALUE;
+ test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
+ mapped_hplmn_sst_presence = false;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
mapped_hplmn_sst = 0;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
@@ -436,6 +438,8 @@ static void test2_func(abts_case *tc, void *data)
sst = 3;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
sd.v = 0x000080;
+ test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
+ mapped_hplmn_sst_presence = false;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].
mapped_hplmn_sst = 0;
test_ue->requested_nssai.s_nssai[test_ue->requested_nssai.num_of_s_nssai].