Compare commits

...

209 Commits

Author SHA1 Message Date
Sukchan Lee
9087a480a8 Update document for v2.4.8 2022-06-12 17:06:36 +09:00
Sukchan Lee
9d43646816 Release v2.4.8 2022-06-12 16:29:24 +09:00
Sukchan Lee
240c10888d [GTP] Fixed bugs if gNB changed (#1515, #1586) 2022-06-12 15:54:27 +09:00
Sukchan Lee
9c3b7dfe4b Added RRCEstablishmentCause to Test-Msg Param 2022-06-12 14:32:53 +09:00
Sukchan Lee
2aa40ca8c8 [PFCP] Added Data Status IE (#1582) 2022-06-12 09:02:59 +09:00
Sukchan Lee
12353178fb Upgrade PFCP to v16.9.1 (#1581) 2022-06-11 23:51:00 +09:00
Sukchan Lee
b98c2c13f6 [SUCI] Handling exceptions for invalid RI (#1570)
If Routing Indicator is wrong, we forcely set to '0'.
2022-06-10 23:19:00 +09:00
Sukchan Lee
9d94b33c7b meson: Rollback libmicrohttpd >= 0.9.40
Ubuntu 18.04 (bionic) should continue to be supported until April 2023.
So I modified mhd_server to support older versions of libmicrohttpd.
2022-06-10 21:35:37 +09:00
Sukchan Lee
6c5a8a135a Reorder smf_gtp_node objects free (#1593)
smf_gtp_node_pool were properly freed.

However, the seqence was wrong, so we got a warning message.

To solve this problem, I've moved smf_gtp_node_alloc/free
from gtp_path.[ch] to context.[ch]
2022-06-10 21:08:15 +09:00
Pau Espin Pedrol
b116630fe8 meson: Depend explicitly on libmicrohttpd >=0.9.61 (#1595)
Recent commit re-enabling SBI HTTP/1.1 support
(10bdf39505cf525b95886c140b3c2e82e7427d29) started using libmicrohttpd's
API MHD_create_response_from_buffer_with_free_callback(), which is only
available starting from v0.9.61.
As a result, compilation in xUbuntu 18.04 started failing with errors
about the function not being found, since it ships with libmicrohttpd
v0.9.59.
Depending on 0.9.61 is fine since it's quite old (november 2018) and all
major current distros should for sure have an >= one. Let's simply bump
the version check so that it fails in an informative manner.
2022-06-10 20:53:55 +09:00
Pau Espin Pedrol
28089e2b59 [SMF] Fix smf_gtp_node objects not freed during shutdown (#1593) 2022-06-10 00:06:13 +09:00
Sukchan Lee
b1e7477904 [CORE] Improve logging error in PFCP (#1591) 2022-06-09 23:36:33 +09:00
Pau Espin Pedrol
5238771295 [CORE] Improve logging error in ogs_gtp_sendto() (#1591) 2022-06-09 23:32:11 +09:00
Carlos Giraldo
cfe21c61da Structure AMF and MME metrics code similar to SMF (#1590)
* AMF metrics initial support

* MME metrics initial support

* set amf/mme metrics.[c|h] similar to smf
2022-06-09 21:39:03 +09:00
Sukchan Lee
0b97954208 Re-added to handle an exceptional case (#1589) 2022-06-09 21:35:59 +09:00
Bostjan Meglic
5084f6a71d [AMF] Add support for SUCI protection schemes A and B (#1589)
For null protection scheme the SUCI needs to be BCD encoded. Whereas for
protection scheme profiles A and B the SUCI needs to be converted from
hexadecimal to ASCII.

This still needs the support for protection schemes A and B in UDM to
work.
2022-06-09 21:27:58 +09:00
Carlos Giraldo
109949d335 MME initial metrics support (#1587) 2022-06-09 06:23:51 +09:00
Pau Espin Pedrol
9e25482d99 [SMF] Gn: Fixes handling/transmitting APN-AMBR IE (#1588) 2022-06-09 06:22:56 +09:00
Carlos Giraldo
816575dc8d AMF metrics initial support (#1585) 2022-06-08 17:54:46 +09:00
Pau Espin Pedrol
28e40a0f1b Initial metrics support based on Prometheus (#1571)
* Initial metrics support based on Prometheus

This commit introduces initial support for metrics in open5gs.

The metrics code is added as libogsmetrics (lib/metrics/), with a well
defined opaque API to manage different types of metrics, allowing for
different implementations for different technologies to scrap the
metrics (placed as lib/metrics/<impl>/. The implementation is right now
selected at build time, in order to be able to opt-out the related dependencies
for users not interested in the features. 2 implementations are already
provided in this commit to start with:
* void: Default implementation. Empty stubs, acts as a NOOP.
* prometheus: open5gs processes become Prometheus servers, offering
  states through an http server to the Prometheus scrappers. Relies on
  libprom (prometheus-client-ci [1] project) to track the metrics and format
  them during export, and libmicrohttpd to make the export possible through
  HTTP.

[1] https://github.com/digitalocean/prometheus-client-c

The prometheus-client-c is not well maintained nowadays in upstream, and
furthermore it uses a quite peculiar mixture of build systems (autolib
on the main dir, cmake for libprom in a subdir). This makes it difficult
to have it widely available in distros, and difficult to find it if it
is installed in the system. Hence, the best is to include it as a
meson subproject like we already do for freeDiameter. An open5gs fork is
requried in order to have an extra patch adding a top-level
CMakeList.txt in order to be able to includ eit from open5gs's meson
build. Furthermore, this allows adding bugfixes to the subproject if any
are found in the future.

* [SMF] Initial metrics support

* [SMF] Add metrics at gtp_node level

* docs: Add tutorial documenting metrics with Prometheus
2022-06-08 05:51:02 +09:00
Pau Espin Pedrol
a9badd5520 GTP, SMF: More dec/enc improvements in QoS Profile IE MBR and GBRE fields (#1584) 2022-06-07 22:13:53 +09:00
Sukchan Lee
18cca7f5e4 Re-enabling HTTP/1.1 (#1570) 2022-06-06 22:20:52 +09:00
Sukchan Lee
828fa23d16 Increase Apply Action size to 2 bytes (#1581) 2022-06-06 21:12:18 +09:00
mitmitmitm
a6abe1fffb [NRF] Don't abort if there are too many registered NF instances (#1579)
Reply with an error instead.
2022-06-06 20:54:59 +09:00
Pau Espin Pedrol
7dd5d27a71 [GTPv1] Several QoS Profile IE enc/dec fixes and improvements (#1575) 2022-06-03 06:56:28 +09:00
Pau Espin Pedrol
e32139009b [SMF] Gn: Avoid building QoS Profile IE twice in UpdatePdpContextResp (#1574) 2022-06-03 01:02:14 +09:00
Pau Espin Pedrol
502a886e43 [CORE] ogs-sockaddr: Fix trailing whitespace (#1573) 2022-06-02 20:20:16 +09:00
Pau Espin Pedrol
d99382d5bc [CORE] Improve log error messages in ogs_ipsubnet() (#1572) 2022-06-02 20:19:55 +09:00
Sukchan Lee
8b3fa5ff9f Follow-up the contribution #1566, #1567 2022-05-31 21:44:53 +09:00
Pau Espin Pedrol
e1e8018919 [SMF] Avoid crash if Create{Session,PdpContext}Resp fails to be sent (#1566)
* [SMF] Gn: Drop unreachable return line

* [SMF] Avoid crash if Create{Session,PdpContext}Resp fails to be sent

Crash spotted in a running open5gs-smfd process, triggered by:
ERROR: ogs_gtp_sendto() failed (1:Operation not permitted) (../lib/gtp/path.c:119)
ERROR: ogs_gtp_xact_commit: Expectation `rv == OGS_OK' failed. (../lib/gtp/xact.c:730)
ERROR: smf_gtp2_send_create_session_response: Expectation `rv == OGS_OK' failed. (../src/smf/gtp-path.c:451)
FATAL: smf_gsm_state_wait_pfcp_establishment: Assertion `OGS_OK == smf_gtp2_send_create_session_response( sess, gtp_xact)' failed. (../src/smf/gsm-sm.c:676)

* [SMF] Avoid crash if Delete{Sesson,PdpContext}Resp fails to be sent

Let's simply continuing with release of the session, there's not much we
can do about it. Peer will eventually realize the conn is no longer
there.
2022-05-31 21:27:42 +09:00
Pau Espin Pedrol
c2bda0b576 [GTP] Several fixes and improvements around ogs_gtp_xact_find_by_xid (#1567)
* [GTP] Add missing msg types to ogs_gtp_xact_get_stage()

* [GTP] Avoid returning wrong xact by xif if none found

* [GTP] Avoid crash if ogs_gtp_xact_get_stage() fails

* [GTP] Rename s/ogs_gtp_xact_get_stage/ogs_gtp2_xact_get_stage/
2022-05-31 21:24:00 +09:00
Sukchan Lee
b6f2146594 [SGWC] Update remote PGW GTPv2-C address (#1560)
In Create Sesion Response, we updated remote PGW GTPv2-C address.
2022-05-28 17:06:36 +09:00
Miguel
78b1dc77ff Update open5gs-dbctl (#1562)
I added four additional commands which are useful in case not using the GUI (add UE using a specific APN, add UE using a specific slice and APN, modify a slice adding an APN, modify an UE adding a new slice + APN)
2022-05-28 11:10:03 +09:00
endika
de0ba3f9dc fix tipo in amf logs (#1558) 2022-05-26 20:12:30 +09:00
Pau Espin Pedrol
c18e9f32cb [PGW] Gy+PFCP improvements (#1555)
* [SMF] Gy,PFCP: Improve {Time,Volume} {Threshold,Quota} handling

* [UPF] Implement URR Usage Report for ValidityTime/TimeQuota/TimeThreshold

* [UPF] Implement Usage report trigger for Volume Quota/Threshold

* [SMF] Set Gy Reporting-Reason based on PFCP Report Trigger
2022-05-24 22:54:30 +09:00
Bostjan Meglic
2c2ce143a3 Fix minor typos (#1554)
* Fix minor typo in log output

* Remove unused struct members
2022-05-24 21:01:54 +09:00
Sukchan Lee
933f0b04c7 [TEST] Added IPv6 in GTPU (#1515) 2022-05-23 23:51:02 +09:00
Sukchan Lee
7d496e182b Update document for v2.4.7 2022-05-21 19:48:56 +09:00
Sukchan Lee
dd845a2bb2 Release v2.4.7 2022-05-21 19:22:11 +09:00
Sukchan Lee
1679f57ac7 [CORE] fix the linked-list bug (#1187) 2022-05-21 18:54:42 +09:00
Pau Espin Pedrol
b6fe640641 [SMF] Gy CCR: Clarify use of Reporting-Request and set it to FINAL in TERMINATION_REQ (#1552) 2022-05-21 06:00:56 +09:00
Sukchan Lee
a6927e18e6 [SBI] fixed mem leak SessionManagement (#1551) 2022-05-21 17:51:31 +09:00
Bostjan Meglic
8efa364f89 Change handling of SessionManagementSubscriptionData as an array (#1551)
According to the following standards the response to the endpoint
/nudm-sdm/${supi}/sm-data should be an array of
SessionManagementSubscriptionData objects, instead of only one object.

TS 29.503 version 16.6.0
TS 29.505 version 16.4.0

UDR now responds to the request with only item in the array.
UDM copies all items as is.
SMF uses only the first item in the array, even if there are more
present.
2022-05-20 17:33:49 +09:00
Pau Espin Pedrol
43a7259781 [SMF] Prevent concurrent access to ogs_pool allocating smf_event (#1546) 2022-05-20 05:57:27 +09:00
Supreeth Herle
aba1867902 Fix AN-Trusted AVP sent in CCR (#1542)
AN-Trusted AVP is only relevant for non-3GPP access networks e.g. WLAN.
This commit adds a check for non-3GPP access network in order to include
AN-Trusted AVP in CCR or not.
Also, clears the M bit for AN-trusted AVP as per TS 29.212 version 16.4.0, Table 5.4.0.1
2022-05-19 13:25:49 +09:00
Sukchan Lee
12d189af07 Document Update 2022-05-17 23:37:41 +09:00
Sukchan Lee
d6c8d49ef4 Update Document for v2.4.6 2022-05-17 23:30:16 +09:00
Sukchan Lee
1983d9d7a7 Release v2.4.6 2022-05-17 22:44:05 +09:00
Sukchan Lee
6710c13a44 update it 2022-05-17 21:44:52 +09:00
Sukchan Lee
67fd2efd76 [HOTFIX] Receive PTI information 2022-05-18 16:04:51 +09:00
Sukchan Lee
c6c8dc1256 [PFCP] Support Multi-CP with One-UP
A problem occurred when there was one SGWU/UPF and multiple SGWC/SMF.

When SGWU and UPF create a session, if the SEID is the same,
the existing session information is used without creating an additional session.

These problems were solved by using the F-SEID including IP information
in the process of checking the existing session.
2022-05-18 10:29:58 +09:00
Pau Espin Pedrol
46621538af [SMF] Improve 3GPP-User-Location-Info in Gn,Gx,Gy (#1539)
* [GTP] Fix trailing whitespace

* [SMF] Improve 3GPP-User-Location-Info in Gn,Gx,Gy
2022-05-17 10:29:11 +09:00
Sukchan Lee
b2f2016a67 Fix the compile error 2022-05-15 23:40:51 +09:00
Sukchan Lee
e0a487f479 [SMF] Optimiza Session Modification Message
For video in VoNR, multiple QosFlow is required in one session.

In the past, since only one Session Modification Message was supported,
QoS-Flow was put into several Session Messages one by one and processed.

Now that multiple QoS-Flows can be supported,
it is optimized to process one session modification message.
2022-05-15 23:35:41 +09:00
Sukchan Lee
a7e2a071e0 Merge branch 'main' of https://github.com/open5gs/open5gs into main 2022-05-15 22:38:38 +09:00
Sukchan Lee
f97f5f794d Merge branch 'althea-net-sctp_crash_upstream' into main 2022-05-15 22:38:29 +09:00
Sukchan Lee
afc562f7d5 [MME] refine Pull Request (#1497) 2022-05-15 22:37:38 +09:00
Sukchan Lee
478723203f Merge branch 'sctp_crash_upstream' of https://github.com/althea-net/open5gs into althea-net-sctp_crash_upstream 2022-05-15 22:22:01 +09:00
Sukchan Lee
c391ac1334 [SMF] Apply 5G Core into GSM (#1498) 2022-05-15 06:27:54 +09:00
Pau Espin Pedrol
fe7f9d85bb [SMF] Store IMEI from GTPv1C/2C and append AVP in Gy CCR (#1535) 2022-05-14 21:32:32 +09:00
Pau Espin Pedrol
c5715d6695 [SMF] Gy CCR: append 3GPP-RAT-Type AVP (#1536) 2022-05-14 06:15:28 +09:00
Sukchan Lee
bb4a8f34d4 [AMF] Fix the bug NGResetAck (#1525) 2022-05-14 02:43:01 +09:00
Sukchan Lee
71572ae563 [PFCP] fixed memcpy (#1531)
dnn ‘memcpy’ reading 808 bytes from a region of size 128
2022-05-13 18:26:54 +09:00
Sukchan Lee
e2159b1240 [SMF] memory free Charging Characteristics (#1532) 2022-05-13 18:18:04 +09:00
Pau Espin Pedrol
99f59be5d7 [SMF] Store Charging Characteristics IE from GTPv1C/2C and append AVP in Gy CCR (#1532) 2022-05-13 06:32:20 +09:00
Sukchan Lee
4d2f7726b9 X2 handover with SGW change (#1367, #1459) 2022-05-12 22:52:36 +09:00
Pau Espin Pedrol
11d4be1779 [SMF] Store Selection Mode IE from GTPv1C/2C and append as 3GPP-Selection-Mode AVP in Gy CCR (#1530)
* [GTPv1C] Make Selection Mode IE uint8

* [SMF] Store Selection Mode in GTPv1C and GTPv2C

* [SMF] Gy CCR: append 3GPP-Selection-Mode AVP
2022-05-12 22:43:12 +09:00
Pau Espin Pedrol
5d478e2488 Pespin/pr (#1529)
* [SMF] rename function s/gtp/gtp2/

* [SMF] Store GTPC version in session

So far we always depended on an xact being present in the code path in
order to know which kind of session it is (GTPv1C vs GTPv2C). Let's
instead store that information in smf_sess_t so that we have it always
available in an easy way.

* [SMF] Move smf_sess_t GTPv1C specifics into gtp substruct

* [SMF] Gy CCR: append 3GPP-NSAPI AVP
2022-05-12 21:42:45 +09:00
Sukchan Lee
333e53d0dd Update sponsor size 2022-05-11 20:45:16 +09:00
Sukchan Lee
53a96022d9 Merge branch 'main' of https://github.com/open5gs/open5gs into main 2022-05-11 20:40:19 +09:00
Sukchan Lee
908d5884dc Add Telet Sponsor 2022-05-11 20:40:03 +09:00
Pau Espin Pedrol
e8d6b0be20 [SMF] Append PDP-Address AVP to Gy CCR msg (#1527)
* [SMF] Append PDP-Address AVP to Gy CCR msg

* [SMF] Gy CCR: Move some AVPs under Service-Information/PS-Information

They belong there. Nokia infocenter documentation seems to be document
the possibility to configure its software to have it in top level, but
that's not what 3GPP TS 32.299 states, so let's stick to it.

* [SMF] Gy CCR: append 3GPP-PDP-Type AVP

* [SMF] Gy CCR: append 3GPP-Charging-Id AVP

* [SMF] Gy CCR: append SGSN-Address AVP

* [SMF] Gy CCR: append GGSN-Address AVP
2022-05-11 15:53:24 +09:00
Sukchan Lee
7a9d06097e [PFCP] fix the unnecessary code (#1523) 2022-05-10 22:58:19 +09:00
Pau Espin Pedrol
3a28ddce37 [PFCP] Fix typo in log line (#1526) 2022-05-10 22:40:32 +09:00
Supreeth Herle
6ffdce598a Fix attach reject when ULA subscription data does not contain MSISDN (#1524)
Issue:
When the ULA - Subscription Data does not contain MSISDN, the Create Session Request
from MME to SGW does not contain MSISDN IE resulting in SMF throwing following log

smf        | 05/09 15:20:53.683: [smf] ERROR: No MSISDN (../src/smf/s5c-handler.c:82)
sgwc       | 05/09 15:20:53.683: [sgwc] ERROR: No Context in TEID (../src/sgwc/s5c-handler.c:104)
mme        | 05/09 15:20:53.683: [mme] ERROR: No Context in TEID (../src/mme/mme-s11-handler.c:122)

As per 3GPP TS 29.274 version 16.5.0, table 7.2.1-1: MSISDN IE shall only be included
in Create Session Request if its provided in subscription data from the HSS. This commit
fixes this by removing the mandatory MSISDN IE check in SMF.
2022-05-10 21:23:03 +09:00
Sukchan Lee
6e81564972 Add new sponsor 2022-05-05 00:06:24 +09:00
Pau Espin Pedrol
76fecdb54e [SMF] Store MSISDN from GTPC and pass it in Gy CCR (#1519) 2022-05-04 05:37:44 +09:00
Pau Espin Pedrol
aa6f3ef8d6 [SMF] gn-handler: Fix typo in error message (#1517) 2022-05-03 21:14:19 +09:00
Sukchan Lee
3508e09a41 [GTPU] IPv6 RS/RA with QFI Extended Header (#1506) 2022-04-30 11:50:30 +09:00
Sukchan Lee
b558da30c6 [GTPU] Fixed to Send Unnecessary EndMarker (#1506) 2022-04-30 10:23:12 +09:00
Sukchan Lee
de2ecd6400 [GTP2] Fixed handling multi-bearer messages(#1498) 2022-04-29 21:28:16 +09:00
Abderaouf KHICHANE
41f743af62 update instructions for adding a subscriber with Python (#1507) 2022-04-27 21:36:34 +09:00
Sukchan Lee
d50a5a44f9 [SBI] cJSON v1.7.7 -> v1.7.15 (#1503) 2022-04-23 02:42:53 +09:00
Pau Espin Pedrol
2de12e32f4 [SMF] Integrate session tear down cycle into sess->sm (#1500)
* [SMF] smf_sm.c Fix indentation

* [SMF] gsm-sm: log fsm events

* [SMF] Integrate session tear down cycle into sess->sm
2022-04-20 21:42:18 +09:00
Spencer Sevilla
23ef30553e initial draft of sctp crash fix 2022-04-18 11:56:43 -07:00
Sukchan Lee
79de674fd8 [PFCP] F-TEID allocation by SMF (#1466) 2022-04-16 14:08:56 +09:00
Pau Espin Pedrol
5f979d0cc3 [SMF] Parallelize Gx+Gy CCR Initial (#1491)
There's no real need to having to wait until Gx is processed in order to
set up Gy. This speeds up time required to set up the UE session.
2022-04-15 07:00:32 +09:00
Sukchan Lee
433d5f6bf3 Distinguish the type of session creation 2022-04-14 17:34:55 +09:00
Sukchan Lee
80cd9d725f [SBI] fixed HTTP2 header values is 0 (#1488) 2022-04-14 11:28:37 +09:00
Sukchan Lee
28746c1cd8 [SMF] Change gtp_message to gtp2_message in SM 2022-04-14 11:20:10 +09:00
Sukchan Lee
bb5d497298 [SMF] fix an invalid error GTP message 2022-04-14 11:18:21 +09:00
Sukchan Lee
079bb5c40e Remove sctp test in MacOSX CI (#1489) 2022-04-14 10:31:20 +09:00
Pau Espin Pedrol
e61b469489 [SMF] Inegrate session setup cycle into sess->sm (#1489)
It allows for much better control on the lifecycle of the session, and
already shows some missing tear down paths in case of errors.
It also clarifies the existence of "sess" pointer in several paths.

The code also becomes clearer overall, since all the transitions and
logic to send next messages are put together.

Tear down of the session will be integrated into gsm-sm in a follow-up
patch.

The 5gc session setup is only partially moved to gsm-sm, and left as an
exercise for users wishin to improve 5gc support.
2022-04-14 10:30:58 +09:00
Pau Espin Pedrol
e3da7c9934 Rename GTPv2C specifics to gtp2 prefix (#1485)
In the past only GTPv2C was supported, and had the "gtp" generic prefix.
Later on, GTPv1C support was added, and "gtp1" prefix was used.
Let's move GTPv2C specific bits to have "gtp2" prefix too, and leave
"gtp" prefix for generic stuff among different GTP versions.
2022-04-13 07:07:39 +09:00
Supreeth Herle
8c22d8a20c Send EMM Cause when Attach Request type is not same as HSS Network-Access-Mode (#1484)
This commit adds EMM Cause to Attach accept message when
Attach Request has COMBINED EPS IMSI ATTACH but the HSS
Network-Access-Mode is configure for EPS ONLY.
2022-04-13 07:06:49 +09:00
Sukchan Lee
e5ff03b249 [SBI] Change the reference count (#1440)
Change the client's reference count method
to use the same method as nf_instance
2022-04-10 20:09:27 +09:00
Sukchan Lee
49c34605db [SBI] fixed the SMF discover bug (#1440) 2022-04-09 13:24:40 +09:00
Sukchan Lee
ff242cd6ea [Gy] Follow-up PRs (#1479) 2022-04-09 10:41:02 +09:00
Pau Espin Pedrol
2be12903cb [SMF] Introduce optional Gy interface support (#1479)
The use of the Gy interface (SMF acting as CTF towards an OCS node) is
mandated through configuration file. Default value "enable: auto" will
only make use of it in case a Diameter peer announcing support for the
Credit-Control Application is found.

Upon subscriber session creation, and after auth check over Gx, the SMF
will create a Gy session with the OCS and only after that step the SMF
will accept the session back to the subscriber.
The OCS may then grant some traffic volumes/time and ask to be notified
back with updated measurements.
In order to get the measurements, the SMF relies on PFCP URR configured
to the UPF through Session Repoort Request messages.
When closing the subscriber session, the SMF will also terminate the Gy
session at the OCS.

So far only some specifics parts of the Gy interface as well as the PFCP
side are implemented. Those should be enough to at least have
volume/time thresholds granted by the OCS, which then will be able to
track subsriber resource use.

This patch doesn't implement the OCS side of the Gy interface, that's
left as a future exercise. The interface was tested using an OCS
emulator implemented in TTCN-3 [1]

[1] https://cgit.osmocom.org/osmo-ttcn3-hacks/
2022-04-09 08:26:28 +09:00
Pau Espin Pedrol
7455424d29 Fix trailing whitespace (#1478) 2022-04-09 08:19:59 +09:00
Sukchan Lee
832ab156e9 Revert "Revert "Functionality for send sms with using IMS service. (#1477)""
This reverts commit b732d7bcc5.
2022-04-09 00:45:37 +09:00
Sukchan Lee
0b3df3e3db Revert "Introduce Gy interface (#1471)"
This reverts commit 106f2729c3.
2022-04-09 00:45:26 +09:00
Sukchan Lee
b5ad0feffc Revert "[Gy] use WARN log-level if No Gy Diameter Peer"
This reverts commit 05551f120f.
2022-04-09 00:45:14 +09:00
Sukchan Lee
b732d7bcc5 Revert "Functionality for send sms with using IMS service. (#1477)"
This reverts commit aa6368132e.
2022-04-09 00:42:43 +09:00
Sukchan Lee
05551f120f [Gy] use WARN log-level if No Gy Diameter Peer 2022-04-09 00:39:21 +09:00
Pau Espin Pedrol
106f2729c3 Introduce Gy interface (#1471)
TODO:

* Use an event for the report, like SMF_EVT_N4_TIMER?

*  Properly set Service identifier in Gy CCR

* SMF: Properly set pkt/octet volumes in Gy CCR
** Update when receiving PFCP Modify Response.

* Figure out best way to require Gy through config file in open5gs-smfd.

* Create a new sess-sm.c which handles smf_sess_t state through
  Gx+Gy+PFCP creation, modification and tear down. This way we can do
stuff in parallel, for instance Gx+Gy. It will alsoavoid duplicating
some code paths due to Gy being optional.
2022-04-09 00:08:58 +09:00
EugeneBogush
aa6368132e Functionality for send sms with using IMS service. (#1477)
* Update

* update

* Update

* update

* new version of profile for send sms

* update

* update

Co-authored-by: root <root@lfv.unassigned-domain>
Co-authored-by: eug <eug@lfv.unassigned-domain>
2022-04-08 23:20:06 +09:00
Pau Espin Pedrol
fb8ebcdbea [UPF] Add initial support for URR Usage Report (#1476) 2022-04-08 23:10:42 +09:00
Pau Espin Pedrol
52672cff65 [DIAM] Add Gy interface support to lib/diameter (#1474)
This commit adds required blocks in lib/diameter to be able to handle Gy
messages later in open5gs apps.

The Gy interface is mainly decribed in 3GPP TS 32.299  and 3GPP TS
32.251, which in turn refers to Diameter protcols defined in RFC4006.
This interface allows charging managment through an external OCS node.
2022-04-08 21:13:02 +09:00
Pau Espin Pedrol
0df2e9f0ba [UPF] cosmetic: Fix trailing whitespace (#1473) 2022-04-08 21:12:52 +09:00
Pau Espin Pedrol
77f7bb7af7 [PFCP] Use proper IE to signal triggers in Usage Report (#1472)
The "Report Triggers" is sent SMF->UPF to tell in which situations a
report should be sent.
The "Usage Report Trigger" is sent UPF->SMF to indicate which situation
triggered the report.
2022-04-08 21:12:42 +09:00
Pau Espin Pedrol
8286b1c417 [SMF] Gx: Fix crash receiving DIAMETER_UNABLE_TO_DELIVER (#1469) 2022-04-06 23:57:55 +09:00
Pau Espin Pedrol
5be48be634 [SMF] Gx: Prevent sending Gx messages to non-PCRF Diameter peers (#1468) 2022-04-06 20:48:26 +09:00
Sukchan Lee
110a63fdfa [SMF] Handle for PCRF not to respond (#1445) 2022-04-03 22:49:12 +09:00
Sukchan Lee
e213f65406 Improve data-path performance using talloc_pool()
allocate a talloc pool for GTP to ensure it doesn't have to go back
to the libc malloc all the time.
2022-04-02 13:36:23 +09:00
Sukchan Lee
1c9a48bfb1 [Doc] Update CentOS Stream 8 (#1450) 2022-04-01 22:33:49 +09:00
Sukchan Lee
77f66e1f0e Migrating to CentOS Stream 8 in Vagrant (#1450) 2022-04-01 22:28:32 +09:00
Sukchan Lee
3121d183f0 [HSS/PCF] Store IMEISV instead of IMEI (#1464) 2022-04-02 00:46:05 +09:00
Sukchan Lee
8f603e2049 [WebUI] Added IMEI in View (#1464) 2022-04-01 20:08:20 +09:00
Sukchan Lee
35201f6ed1 Fix the MacOSX CI (#1454) 2022-03-31 23:06:52 +09:00
Sukchan Lee
24d20bb20b Update automatic CI (#1454) 2022-03-31 22:55:27 +09:00
Sukchan Lee
f2aa15d99f Added MacOSX to the Running OS for CI (#1454) 2022-03-31 21:31:10 +09:00
Sukchan Lee
c76c7d597d Oops! Rollback Meson Continuous integration 2022-03-31 20:26:58 +09:00
Sukchan Lee
9c4287f467 update it1 2022-03-31 20:24:31 +09:00
Sukchan Lee
2def8bb31b update it 2022-03-31 19:51:51 +09:00
EugeneBogush
f557fc8eaa Add/update current imei of UE in subscriber profile (#1464)
* first commit

* fix

Co-authored-by: root <root@lfv.unassigned-domain>
2022-03-31 19:35:30 +09:00
Sukchan Lee
82241f5b84 Added Meson Continuous Integration (#1454) 2022-04-01 02:31:57 +09:00
Pau Espin Pedrol
fbfb72c1b7 [PFCP] Support multiple Usage Report IEs in all messages (#1461)
* [PFCP] Properly check down_data_report inclusion building SessionReportRequest

* [PFCP] Support multiple Usage Report IEs in all messages
2022-03-31 09:43:35 +09:00
Sukchan Lee
038fb680f4 Revert configuration for backward compatibility 2022-03-31 02:15:13 +09:00
Sukchan Lee
da8c934326 [Test] Fix the SBI running[1] 2022-03-28 23:09:24 +09:00
Sukchan Lee
88016a769f [SMF] fix missing initialization memory (#1458) 2022-03-28 22:22:24 +09:00
Pau Espin Pedrol
acd6610508 [SMF] Gx: Add Destination-Host AVP to CCR (#1458)
Catch Origin-Host during CCA and set it as Destination-Host during
subsequent CCRs. This way we ensure UPDATE/TERMINATION Requests are sent
back explicitly to the same Diameter peer. Moreover, it seems
freediameter relies on this AVP to properly send the message over the
correct SCTP association when several diameter peers are available.
2022-03-28 22:00:28 +09:00
Pau Espin Pedrol
4b8d3a845a [PFCP] Support associating multiple URRs to a PDR (#1456)
* [PFCP] Fix trailing whitespace in message generation files

* [PFCP] message gen: Support multiple URR ID IEs in Create PDR group

* [PFCP] Support associating multiple URRs to a PDR

According to 3GPP TS 29.244:
"""
A PDR shall contain:
- zero, one or more URRs, which contains instructions related to traffic measurement and reporting.
"""
2022-03-28 21:56:58 +09:00
Sukchan Lee
825b06b6e0 Update document for v2.4.5 2022-03-27 20:12:30 +09:00
Sukchan Lee
12c656efd0 Improve Slice/DNN selection (#1438), (#1440) 2022-03-27 17:50:31 +09:00
Sukchan Lee
ced37a6201 fix the slice issues (#1438), (#1440) 2022-03-26 23:53:53 +09:00
Pau Espin Pedrol
38e2dee17f [PFCP] Handle Measurement Information in Create/Update URR IEs (#1453) 2022-03-26 00:33:32 +09:00
Pau Espin Pedrol
89636fa8d3 [PFCP] Handle Measurement Information in Create/Update URR IEs (#1452) 2022-03-26 00:07:34 +09:00
Pau Espin Pedrol
cc0d147f5c Fix trailing whitespace (#1451) 2022-03-25 23:35:27 +09:00
Pau Espin Pedrol
12bac7a917 [PFCP] Avoid requiring optional fields in Update URR IE (#1449) 2022-03-25 05:58:40 +09:00
Sukchan Lee
41553de7a4 [MME] Exception handle - APN duplicated (#1431) 2022-03-24 21:52:42 +09:00
Sukchan Lee
2cb06b3085 remove pool related configuration (#1431) 2022-03-23 15:14:18 +09:00
Sukchan Lee
224d1caca1 change log-level WARNING to INFO 2022-03-22 22:52:10 +09:00
Sukchan Lee
37af21a88d [MEM] fix the pkbuf problem (#1431) 2022-03-22 22:47:45 +09:00
Sukchan Lee
fe5fd0f760 Update sponsors 2022-03-19 20:26:49 +09:00
Pau Espin Pedrol
ab5f47ef59 [SMF] PFCP Session Report Req: Allow receiving multiple bits in Report Type (#1442)
3GPP TS 29.244 sec 8.2.21 "Report Type" states:
At least one bit shall be set to "1". Several bits may be set to "1".
2022-03-17 16:23:43 +09:00
Sukchan Lee
72ecd1c005 [SMF] Remove T_RELEASE_HOLDING timer 2022-03-17 16:07:19 +09:00
Pau Espin Pedrol
7f6f35fe6f [UPF] Improve logging around IP spoofing (#1441)
* [UPF] Fix Trailing whitespace

* [UPF] Improve logging around IP spoofing

Related: https://github.com/open5gs/open5gs/issues/1435
2022-03-16 21:59:50 +09:00
Sukchan Lee
bf77318602 [MME] re-factor to check a piggybacked ESM (#1431) 2022-03-16 20:48:48 +09:00
Sukchan Lee
a6ec206998 Change EPERM to OGS_EPERM (#1436,#1404) 2022-03-16 20:32:19 +09:00
Pau Espin Pedrol
f060da45d5 [CORE] time: Add APIs to manage NTP 32-bit timestamps (#1439)
These will be further needed in PFCP in the future, as well as in other
Diameter based interfaces (such as Gy).
Let's put all implementation details in APIs so that devs don't need to
care about those details every time.
2022-03-16 11:25:30 +09:00
Pau Espin Pedrol
80ce991aa6 [CORE] Improve SO_BINDTODEVICE error log line (#1436) 2022-03-16 11:25:21 +09:00
Sukchan Lee
bcf53124d5 Improve the socket option configuration (#1404)
o GTP-C Option (Default)
  - so_bindtodevice : NULL

  gtpc:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o GTP-U Option (Default)
  - so_bindtodevice : NULL

  gtpu:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o PFCP Option (Default)
  - so_bindtodevice : NULL

  pfcp:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o SBI Option (Default)
  - tcp_nodelay : true
  - so_linger.l_onoff : false

  sbi:
    addr: 127.0.0.10
    option:
      tcp_nodelay: false
      so_linger:
        l_onoff: true
        l_linger: 10

o NGAP Option (Default)
  - sctp_nodelay : true
  - so_linger.l_onoff : false
ngap:
  addr: 127.0.0.5
  option:
    stcp_nodelay: false
    so_linger:
      l_onoff: true
      l_linger: 10

o NGAP SCTP Option (Default)
  - spp_hbinterval : 5000 (5secs)
  - spp_sackdelay : 200 (200ms)
  - srto_initial : 3000 (3secs)
  - srto_min : 1000 (1sec)
  - srto_max : 5000 (5secs)
  - sinit_num_ostreams : 30
  - sinit_max_instreams : 65535
  - sinit_max_attempts : 4
  - sinit_max_init_timeo : 8000(8secs)
ngap:
  addr: 127.0.0.5
  option:
    sctp:
      spp_hbinterval : 5000
      spp_sackdelay : 200
      srto_initial : 3000
      srto_min : 1000
      srto_max : 5000
      sinit_num_ostreams : 30
      sinit_max_instreams : 65535
      sinit_max_attempts : 4
      sinit_max_init_timeo : 8000
2022-03-15 22:03:50 +09:00
Pau Espin Pedrol
73836c063c [UPF] Fix log typo, trailing whitespace (#1434) 2022-03-15 13:34:32 +09:00
Pau Espin Pedrol
dd5abb79b4 [PFCP] Fix wrong endianess enc of some URR values (#1433)
* [PFCP] Fix trailing whitespace

* [PFCP] Fix wrong endianess enc of some URR values

u32 tlvs are already converted to big endian automatically. Manually
doing so ends up in double conversion and hence in wrong endianness
being sent over the wire.
Similar issue was also fixed recently in the PFCP decoding path.
Related: https://github.com/open5gs/open5gs/issues/1349
2022-03-15 13:34:22 +09:00
Pau Espin Pedrol
5b81802be9 [Gx] Fix trailing whitespace (#1420) 2022-03-08 21:50:20 +09:00
Pau Espin Pedrol
4388f9bf3a [Gx] Use OGS_DIAM_GX_APPLICATION_ID define instead of hardcoded val (#1419) 2022-03-08 21:50:05 +09:00
Sukchan Lee
c1fc25958c Change default to bindtodevice:false 2022-03-08 19:49:16 +09:00
Sukchan Lee
914bb0a40f Merge branch 'sysmocom-pespin/vrf' into main 2022-03-07 22:44:23 +09:00
Sukchan Lee
253e2ad98a [GTP/PFCP] Support VRF (#1404) 2022-03-07 22:43:18 +09:00
Sukchan Lee
c2d10772c6 Merge branch 'pespin/vrf' of https://github.com/sysmocom/open5gs into sysmocom-pespin/vrf 2022-03-07 22:43:10 +09:00
Sukchan Lee
f848785360 Update document (#1412) 2022-03-05 18:50:25 +09:00
Sukchan Lee
a1be48ed50 [SGW-C] fix the crash (#1353) 2022-03-05 11:27:22 +09:00
Sukchan Lee
896370c2e4 [MME] Oops! Remove redundant warning (#1411) 2022-03-04 23:49:45 +09:00
Sukchan Lee
9bf8a84b81 [SGWC] fix the crash (#1353) 2022-03-05 02:58:53 +09:00
Sukchan Lee
79e34260da [SGWC] fix the crash (#1353) 2022-03-03 23:17:28 +09:00
Pau Espin Pedrol
7bddc92322 [GTP] Support binding socket to device
This is useful, among other possible applications, to make use of VRFs [1],
in this case for GTP-C and GTP-U traffic in the PGW.

The bind_dev field is added to the ogs_socknode_t so that it's easy to
extend its use into lots of other sockets being set up based on config
file information.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/vrf.rst
2022-03-02 20:07:51 +01:00
Sukchan Lee
ed3444eef5 Need to increase NF ref_count
1. UE registered and PDU established.
2. PCF does not receive Heartbeat.
 - PCF De-registered state.
 - Since PDU is established, SMF should not remove NF instance
3. PCF re-registered.
 - HERE, WE NEED TO INCREASE NF REFERENCE COUNT.
   Otherwise, NF instance will be removed if PCF is de-registered state
4. UE sends PDU release request.
5. Because SMF knows PCF NF instance, SMF can send PCF delete
2022-03-01 22:02:02 +09:00
Sukchan Lee
3217e93124 [LINUX] initialize struct epoll_event (#1399) 2022-03-01 21:03:27 +09:00
ji3k54j062k7
19120acadc modify building from source md file (#1403)
Signed-off-by: ji3k54j062k7 <ji3k54g4j062k7@gmail.com>
2022-03-01 20:18:47 +09:00
Pau Espin Pedrol
d06acc7f37 Fix trailing whitespace (#1402) 2022-03-01 17:13:40 +09:00
Supreeth Herle
bc69ddfc6d [SMF]: Fix Framed-IPv6-Prefix AVP length in CCR (#1398) 2022-03-01 17:11:28 +09:00
Sukchan Lee
d54e8a43ce [PCRF] Fix Framed-IPv6 Prefix in CCR (#1398) 2022-03-01 17:09:47 +09:00
Pau Espin Pedrol
ba3a046c62 [SMF] Avoid crash if smf_ue_pool is full (1024 UEs) (#1397) 2022-02-28 21:27:27 +09:00
Sukchan Lee
efe37c1e84 [ASN1C] asn.1 issues in NGAP (#1394 from @nkout)
mouse07410/asn1c#89
Found when tried to encode NGAP_CauseRadioNetwork_release_due_to_pre_emption

mouse07410/asn1c#90
Found when tried to decode messages encoded with newer schema
2022-02-26 16:09:38 +09:00
Supreeth Herle
03280d1f5a Fix prefix length in Gx CCR Framed-IPv6-Prefix AVP (#1396)
As per 3GPP TS 23.401 version 15.12.0, section 5.3.1.2.2
The PDN GW allocates a globally unique /64
IPv6 prefix via Router Advertisement to a given UE.

After the UE has received the Router Advertisement message, it
constructs a full IPv6 address via IPv6 Stateless Address
autoconfiguration in accordance with RFC 4862 using the interface
identifier assigned by PDN GW.

For stateless address autoconfiguration however, the UE can
choose any interface identifier to generate IPv6 addresses, other
than link-local, without involving the network.

And, from section 5.3.1.1, Both EPS network elements and UE shall
support the following mechanisms:

/64 IPv6 prefix allocation via IPv6 Stateless Address
autoconfiguration according to RFC 4862, if IPv6 is
supported.
2022-02-26 15:25:08 +09:00
Pau Espin Pedrol
51a75cde26 Pespin/pr (#1395)
* [SMF] Gn: Avoid assert crash if no PDP resources available

* [SMF] Gn: Rearrange IE handling order in CreatePDPContextRequest

Let's handle the GTPC remote addr + TEID first, since those should be
used in the CreatePDPContextResponse ideally if available.

Let's then handle parsing of all IEs not related to bearers/UserPlane,
then those missing, and finally do all the IP resource allocation.
2022-02-25 22:39:44 +09:00
Supreeth Herle
52bc4be547 Bugfix packet filter for pre rel11 LTE devices (#1393)
* Fix conversion from IPFilterRule to packet filter

As per 3GPP TS 24.008, following Packet filter component type identifier
are not supported on the LTE pre release-11 UEs:

IPv4 local address type
IPv6 remote address/prefix length type
IPv6 local address/prefix length type

And,
IPv6 remote address/prefix length type and
IPv6 local address/prefix length type shall be used when both MS and
Network support Local Address in TFTs.

This commit add logic to omit adding local address in packet filters
for compatibility with pre-release LTE 11 devices. The following parameter
could be used to toggle omit/no to omit behavior.

parameter:
	no_ipv4v6_local_addr_in_packet_filter: <true/false>

* Remove logic of supporting pre-release LTE 11 devices in PCRF
2022-02-25 22:11:51 +09:00
Pau Espin Pedrol
3b6da3ddb2 [GTPv1C] Fix sequm not added to EchoResponse and VersionNotSupported (#1390)
According to TS 29.060 they should be added.

section 7.6:
"if it is a request for which a response has been defined, shall be sent
with a Sequence Number"

section 8.2:
"""
Sequence number flag (S) shall be set to "1"
...
For GTP-C messages not having a defined response message for a request
message, i.e. for messages Version Not Supported, RAN Information Relay
and Supported Extension Headers Notification, the Sequence Number shall
be ignored by the receiver.
"
2022-02-24 23:38:52 +09:00
Pau Espin Pedrol
dbd9e8bd78 [GTPv1C] Set EUA spare field to '1111' as per spec (#1388) 2022-02-24 06:03:54 +09:00
Pau Espin Pedrol
3833a73a14 [SMF] incorrect GTPv1C cause with changed APN (#1387) 2022-02-23 20:48:36 +09:00
Sukchan Lee
953a7321c6 [SMF] fix the crash in VoLTE test (#1383) 2022-02-23 20:31:28 +09:00
Pau Espin Pedrol
5ad1b188e4 [SMF] UpdatePDPContext: forward update of remote TEID+IPaddr to UPF (#1383)
* [SMF] typo fixes in commented code

* [SMF] Fix early err return handling UpdatePDPContextRequest

* [SMF] UpdatePDPContext: forward update of remote TEID+IPaddr to UPF

Updating the remote GTP-U IP address and/or TEID on the GGSN is a common
practice, used for instance by an SGSN in a UTRAN network to connect an
HNB(GW) to exchange GTP-U directly with the GGSN. It is also used in
general when doing handovers.
When receiving a UpdatePDPContext with the new address, we need to
forward the update to the UPF so that it takes it into account when
forwarding packets.

This patch only implements updating the information towards the UPF when
GTPv1C is used. Similar approach for GTPv2C (upon receival of Modify
Bearer Request) is still unimplemented.

Related: https://github.com/open5gs/open5gs/issues/1367
2022-02-23 20:21:33 +09:00
Sukchan Lee
af3db1770f [SMF] incorrect GTP cause with changed APN (#1360)
SMF setting incorrect Cause when answering
with a changed APN type IPv4v6 ->IPv4/IPv6
2022-02-23 20:16:04 +09:00
Sukchan Lee
d61127afcc [SMF] fix the seperate DNS in PCO IPCP (#1358) 2022-02-23 17:38:07 +09:00
Pau Espin Pedrol
882548de11 [SMF] UpdPDPCtxRsp: Fix adding 2 IP addresses to one GSN Address IE (#1382)
In the event we have 2 local IP addresses available for use, put the one
having same IP version in "GGSN Address *" IE, and the one with the
other IP version in "Alternative GGSN Address *" IE.

Same fix was applied recently to CreatePDPContextResponse.
2022-02-22 07:00:14 +09:00
Pau Espin Pedrol
b0fc06ab6c Fix trailing whitespace (#1381) 2022-02-22 07:00:06 +09:00
Pau Espin Pedrol
b7698810ac [SMF] s/'Context not found'/'Non-existent'/ in {Update,Delete}PdpContextResponse (#1379)
TS 29.060 sections 7.3.4 and 7.3.6 specify the possible cause values for
UpdatePdpContextResponse and DeletePdpContextResponse.
Together with section 8.2, it becomes clear that 'Non-existent' cause
should be sent instead of 'Context not found' one in those cases.
2022-02-21 22:18:39 +09:00
Sukchan Lee
e3fa731c4a [SBI] fix the timezone string converter (#1376) 2022-02-20 20:18:32 +09:00
Sukchan Lee
420c1d5ad3 [SMF] fix the PCO bug (#1357, #1358)
- SMF can handle PCO ID PAP (0xc023)
- SMF adds DNS servers to PCO IPCP only if UE requested
2022-02-19 16:05:07 +09:00
Sukchan Lee
b4f382d360 [MEM] fix pkbuf problem in multi-threads (#1353)
We should use talloc in multi-threads instead of pkbuf.
Now, pkbuf library only uses single-thread environment.
2022-02-19 09:47:44 +09:00
Pau Espin Pedrol
137ed99dd5 [GTPv1C] Send conditional IE Reordering Required in CreatePDPCtxResp (#1374)
It seems to be actually mandatory in GGSN->SGN directon, though it is
ignored in Release99 upwards. Let's hardcode it to 0 for now, should be
fine in the majority of cases.
2022-02-19 06:36:54 +09:00
Pau Espin Pedrol
f7999a2cad [GTPv1C] Fix outer message length field containing wrong value (#1373)
The mandatory part of the header must be excluded from the header, that
is flags(1)+type(1)+length(2)+teid(4) = 8 bytes.
2022-02-19 06:36:40 +09:00
Pau Espin Pedrol
2056a5b500 [PCRF] Fix trailing whitespace (#1372) 2022-02-19 06:33:46 +09:00
Pau Espin Pedrol
8b1bdf42a2 [SMF] Fix adding 2 IP addresses to one GSN Address IE (#1371)
In the event we have 2 local IP addresses available for use, put the one
having same IP version in "GGSN Address *" IE, and the one with the
other IP version in "Alternative GGSN Address *" IE.
2022-02-19 06:33:19 +09:00
Pau Espin Pedrol
8cc70694db Introduce Gn interface (GTPv1C) Support to PGW (#1351)
* [CORE] tlv: Store mode in ogs_tlv_t

This allows specifying the format of the IE for each individual IE,
hence allowing messages containing IEs formatted in different ways.

This is needed in order to support parsing GTPv1-C, since messages
contain IEs with different structure (TLV vs TV). Hence, this is a
preparation patch to add support for parsing TVs in ogs-tlv.c/.h.

* [CORE] tlv: Support parsing msg with both TLV and TV in it

IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder
doesn't provide with ways to parse messages which contain TV formatted
IEs. This patch adds the relevant types and ways to encode/decode them.

Furthermore, the current parser/builder allows parsing/building messages
containing the exact same format in all its IEs. A new parser function
is added which allows parsing messages of different types (TV, TLV)
mixed in the same message. In order to be able to do so, it uses the
general msg_mode passed to it in order to know the general TLV format
(in essence, the length of the Tag field, and also the length of the
Length field if applicable each IE).

Looking up the instance in the TLV description is left undone and
hadcoded to 0, since the only user so far requiring this API is GTPv1-C,
which has no instances.

* [CORE] tlv: Support repeated tag+instance parsing TLV message

In GTPv2C, repeated IEs (same tag) are easily differentiated by the
Instance byte, which provides info to match different decoded
structures. In GTPv1C though, there's no Instance byte, and we still
encounter repeated IEs (like GSN Address in Create PDP Context Request).
Hence, the TLV decoder needs to be updated to track count of IEs found
(identified by tag+instance, where instance is always 0 in GTPv1C) and
get the proper description index + offset into the decoded structure.

* [GTP]: Move GTPv2-C specifics to its own libgtp subdir

This will allow adding GTPv1-C code by the side. Most GTPv2 code is left
in this patch as "gtp" instead of renaming it to "gtp2" in order to
avoid massive changes. It can be done at a later stage if wanted.

* [GTP] Support generating GTPv1-C messages

* [SMF] Add Gn interface support

This patch introduces GTPv1C support to open5gs-smfd. With it,
open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting
GERAN and UTRAN networks.
2022-02-18 22:23:45 +09:00
Sukchan Lee
3eab4be135 fix MacOSX compile error (#1354, #1355) 2022-02-18 22:00:57 +09:00
Matthew Johnson
7df65e832e Relax systemd requirements (#1368)
* [configs] Remove requires systemd-networkd dep from smfd service

The smf no longer has (never had?) a dependency on systemd-networkd,
and can start and remain operational without systemd-networkd
specifically running.

* [configs] Relax upf dependency on systemd-networkd

The upf relies on systemd-networkd to create the ogstun interface, but
does not communicate with it at runtime. It currently has a "Requires"
dependency specified, which means that the upf will be stopped if
systemd-networkd is ever stopped. Since the upf doesn't actually care
if systemd-networkd is later stopped after ogstun is created, it can
use the weaker "Wants" dependency type, which allows it to keep
running even if systemd-networkd were to be stopped.

Regardless, since it does rely on systemd-networkd specifically to
create the ogstun interface, it should sequence itself "After"
systemd-networkd has been started.

Since the true dependency is ogstun, not systemd-networkd, a cleaner
approach would depend on the specific tunnel device being
available. Systemd exposes this information via device units, but I'm
not sure if they are always consistently named across platforms.
2022-02-16 17:56:14 +09:00
Matthew Johnson
c0ffe1ffe4 Systemd sequencing (#1366)
* [configs] Do not require ogstun for system online

Systemd-networkd will wait for all managed interfaces to be configured
before determining the system is online. Since the ogstun and upf are
more logically an application rather than a system networking service,
don't wait for them to be configured by default.

This breaks the circular dependency between the userspace cellular
core network services and the system's network, which will allow the
cellular core network services to sequence themselves cleanly after
the system's network is up and configured.

* [configs] Sequence network-dependent units after network-online

Since open5gs targets platforms with both ifupdown (debian) and
systemd-networkd (Ubuntu) as core networking providers, this commit
sequences network-dependent core network components after the generic
network-online.target instead of one of the specific provider
targets. This allows the core network to operate correctly with both
systemd-networkd and ifupdown (networking), and fixes the issue
observed in https://github.com/open5gs/open5gs/issues/826 where some
platforms may fail to start cleanly.
2022-02-15 22:33:33 +09:00
Pau Espin Pedrol
757285bf25 Fix trailing whitespace (#1365)
* [SMF] Fix trailing whitespace

* [CORE] Fix trailing whitespace

* [GTP] Fix trailing whitespace
2022-02-14 20:11:04 +09:00
Sukchan Lee
906e7c5046 [UPF] Consider RS message for IP spoofing (#1354) 2022-02-14 20:07:08 +09:00
Sukchan Lee
0e1ab26ee5 Check if Source IP address spoofing (#1354, #1355) 2022-02-14 17:34:22 +09:00
Sukchan Lee
6e30f97097 Fixed typo in Airspan gNodeB 2022-02-13 20:19:21 +09:00
Sukchan Lee
4145b8b543 Added Airpsan 5G commercial gNodeB to the tested 2022-02-12 14:43:14 +09:00
Sukchan Lee
ffcd92c2f3 [SBI] Remove Accept-Encoding in HTTP client 2022-02-12 14:40:48 +09:00
Sukchan Lee
900e888dc1 [SBI] fix crash when no mandatory item (#1350)
NRF crashed if NFService does not have a versions.
Versions are mandatory, we've modified the SBI interface for the safety.
2022-02-05 20:20:45 +09:00
Sukchan Lee
acfcbda8fa [PFCP] remove be32toh() in TLV u32 leaf (#1349) 2022-02-04 00:26:27 +09:00
Pau Espin Pedrol
5fff69306f logging improvements (#1348)
* [SMF] Fix typo in debug message

* [SMF] Add debug messages to follow messages received in N4
2022-02-02 23:23:12 +09:00
Sukchan Lee
9b7ebf9927 Update document 2022-02-01 15:17:04 +09:00
772 changed files with 39469 additions and 13513 deletions

77
.github/workflows/meson-ci.yml vendored Normal file
View File

@@ -0,0 +1,77 @@
name: Meson Continuous Integration
on: [push, pull_request]
jobs:
macos-latest:
name: Build and Test on MacOS Latest
runs-on: macos-latest
steps:
- name: Install MongoDB with Package Manager
run: |
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community
- name: Create the TUN device with the interface name `ogstun`.
run: |
sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.4 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.5 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.5 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.6 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.7 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.8 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.9 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.10 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.11 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.12 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.13 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.14 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.15 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.16 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
- name: Install the dependencies for building the source code.
run: brew install mongo-c-driver libidn libmicrohttpd nghttp2 bison libusrsctp libtins talloc meson
- name: Check out repository code
uses: actions/checkout@main
- name: Setup Meson Build
run: PATH="/usr/local/opt/bison/bin:$PATH" meson setup build
env:
CC: gcc
- name : Build Open5GS
run: ninja -C build
- name: Test Open5GS
run: sudo meson test -C build -v crypt unit
ubuntu-latest:
name: Build and Test on Ubuntu Latest
runs-on: ubuntu-latest
services:
mongodb:
image: mongo
ports:
- 27017:27017
steps:
- name: Create the TUN device with the interface name `ogstun`.
run: |
sudo ip tuntap add name ogstun mode tun
sudo ip addr add 10.45.0.1/16 dev ogstun
sudo ip addr add 2001:db8:cafe::1/48 dev ogstun
sudo ip link set ogstun up
- name: Install the dependencies for building the source code.
run: |
sudo apt update
sudo apt install python3-pip python3-setuptools python3-wheel ninja-build build-essential flex bison git 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
- name: Check out repository code
uses: actions/checkout@main
- name: Setup Meson Build
run: meson setup build
env:
CC: gcc
- name : Build Open5GS
run: ninja -C build
- name: Test Open5GS
run: meson test -C build -v

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# This directory is fetched during first build and is present in this directory
subprojects/freeDiameter
subprojects/libtins
subprojects/prometheus-client-c
subprojects/usrsctp
webui/.next

View File

@@ -2,13 +2,26 @@
If you find Open5GS useful for work, please consider supporting this Open Source project by [Becoming a sponsor](https://github.com/sponsors/acetcom). To manage the funding transactions transparently, you can donate through [OpenCollective](https://opencollective.com/open5gs).
<h3 align="center">Platinum Sponsors</h3>
<table align="center">
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://teletresearch.com/" target="_blank">
<img width="400px" src="https://open5gs.org/assets/img/Telet-logo-v2.png">
</a>
</td>
</tr>
</tbody>
</table>
<h3 align="center">Gold Sponsors</h3>
<table>
<table align="center">
<tbody>
<tr>
<td align="center" valign="middle">
<a href="http://wavemobile.com/" target="_blank">
<img width="260px" src="https://open5gs.org/assets/img/Wavemobile-Logo-Mark-RGB.png">
<img width="222px" src="https://open5gs.org/assets/img/Wavemobile-Logo-Mark-RGB.png">
</a>
</td>
</tr>
@@ -16,14 +29,9 @@ If you find Open5GS useful for work, please consider supporting this Open Source
</table>
<h3 align="center">Silver Sponsors</h3>
<table>
<table align="center">
<tbody>
<tr>
<td align="center" valign="middle" width="222px">
<a href="https://www.auctionsoftware.com/" target="_blank">
<img src="https://open5gs.org/assets/img/asLogonew.png">
</a>
</td>
<td align="center" valign="middle" width="222px">
<a href="https://nextepc.com/" target="_blank">
<img src="https://open5gs.org/assets/img/nextepc_logo.jpg">
@@ -34,13 +42,13 @@ If you find Open5GS useful for work, please consider supporting this Open Source
<img src="https://open5gs.org/assets/img/triple_logo.png">
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle" width="222px">
<a href="https://sdr.eee.strath.ac.uk/" target="_blank">
<img src="https://open5gs.org/assets/img/strath.png">
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle" width="222px">
<a href="https://skylarkwireless.com/" target="_blank">
<img src="https://open5gs.org/assets/img/SkylarkWireless-420x78-Web2-R.png">
@@ -51,21 +59,21 @@ If you find Open5GS useful for work, please consider supporting this Open Source
<img src="https://open5gs.org/assets/img/sysmocom-logo-only.png">
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle" width="222px">
<a href="https://www.p1sec.com/" target="_blank">
<img src="https://open5gs.org/assets/img/2021-logo-P1.svg">
</a>
</td>
</tr>
<tr>
<td align="center" valign="middle" width="222px">
<a href="https://www.ng-voice.com/" target="_blank">
<img src="https://open5gs.org/assets/img/ng-voice-logo_color.png">
</a>
</td>
<td align="center" valign="middle" width="222px">
<a href="https://www.peratonlabs.com/" target="_blank">
<img src="https://open5gs.org/assets/img/peraton-labs-logo-full-color.png">
<a href="http://www.bristol.ac.uk/engineering/research/smart/" target="_blank">
<img src="https://open5gs.org/assets/img/smart-internet-lab.png">
</a>
</td>
</tr>

View File

@@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.5
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <NGAP Server>>
#
# o NGAP Server(all address avaiable)
@@ -96,6 +108,43 @@ logger:
# ngap:
# dev: eth0
#
# o NGAP Option (Default)
# - sctp_nodelay : true
# - so_linger.l_onoff : false
#
# ngap:
# addr: 127.0.0.5
# option:
# stcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# o NGAP SCTP Option (Default)
# - spp_hbinterval : 5000 (5secs)
# - spp_sackdelay : 200 (200ms)
# - srto_initial : 3000 (3secs)
# - srto_min : 1000 (1sec)
# - srto_max : 5000 (5secs)
# - sinit_num_ostreams : 30
# - sinit_max_instreams : 65535
# - sinit_max_attempts : 4
# - sinit_max_init_timeo : 8000(8secs)
#
# ngap:
# addr: 127.0.0.5
# option:
# sctp:
# spp_hbinterval : 5000
# spp_sackdelay : 200
# srto_initial : 3000
# srto_min : 1000
# srto_max : 5000
# sinit_num_ostreams : 30
# sinit_max_instreams : 65535
# sinit_max_attempts : 4
# sinit_max_init_timeo : 8000
#
# <GUAMI>
#
# o Multiple GUAMI
@@ -232,6 +281,18 @@ amf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -264,49 +325,10 @@ parameter:
max:
#
# pool:
# usrsctp:
# udp_port : 9899
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# sockopt:
# no_delay : true
#
sockopt:
#
# sctp:
# heartbit_interval : 5000 (5secs)
# sack_delay : 200 (200ms)
# rto_initial : 3000 (3secs)
# rto_min : 1000 (1sec)
# rto_max : 5000 (5secs)
# max_num_of_ostreams : 30
# max_num_of_istreams : 65535
# max_attempts : 4
# max_initial_timeout : 8000(8secs)
# usrsctp_udp_port : 9899
#
sctp:
usrsctp:
#
# time:
@@ -336,3 +358,17 @@ sctp:
# handover:
# duration: 500
time:
#
# metrics:
#
# <Metrics Server>
#
# o Metrics Server(http://<any address>:9090)
# metrics:
# addr: 0.0.0.0
# port: 9090
#
metrics:
addr: 0.0.0.0
port: 9090

View File

@@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.11
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
ausf:
sbi:
- addr: 127.0.0.11
@@ -104,6 +116,18 @@ ausf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -114,9 +138,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -138,30 +159,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.15
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
bsf:
sbi:
- addr: 127.0.0.15
@@ -106,6 +118,18 @@ bsf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -116,9 +140,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -140,30 +161,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -26,12 +26,11 @@ logger:
hss:
freeDiameter: @sysconfdir@/freeDiameter/hss.conf
# sms_over_ims: "sip:smsc.mnc001.mcc001.3gppnetwork.org:7060;transport=tcp"
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -52,27 +51,3 @@ parameter:
# gnb: 64
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:

View File

@@ -47,6 +47,43 @@ logger:
# s1ap:
# dev: eth0
#
# o S1AP Option (Default)
# - sctp_nodelay : true
# - so_linger.l_onoff : false
#
# s1ap:
# addr: 127.0.0.2
# option:
# stcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# o S1AP SCTP Option (Default)
# - spp_hbinterval : 5000 (5secs)
# - spp_sackdelay : 200 (200ms)
# - srto_initial : 3000 (3secs)
# - srto_min : 1000 (1sec)
# - srto_max : 5000 (5secs)
# - sinit_num_ostreams : 30
# - sinit_max_instreams : 65535
# - sinit_max_attempts : 4
# - sinit_max_init_timeo : 8000(8secs)
#
# s1ap:
# addr: 127.0.0.2
# option:
# sctp:
# spp_hbinterval : 5000
# spp_sackdelay : 200
# srto_initial : 3000
# srto_min : 1000
# srto_max : 5000
# sinit_num_ostreams : 30
# sinit_max_instreams : 65535
# sinit_max_attempts : 4
# sinit_max_init_timeo : 8000
#
# <GTP-C Server>>
#
# o GTP-C Server(all address avaiable)
@@ -362,49 +399,10 @@ parameter:
max:
#
# pool:
# usrsctp:
# udp_port : 9899
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# sockopt:
# no_delay : true
#
sockopt:
#
# sctp:
# heartbit_interval : 5000 (5secs)
# sack_delay : 200 (200ms)
# rto_initial : 3000 (3secs)
# rto_min : 1000 (1sec)
# rto_max : 5000 (5secs)
# max_num_of_ostreams : 30
# max_num_of_istreams : 65535
# max_attempts : 4
# max_initial_timeout : 8000(8secs)
# usrsctp_udp_port : 9899
#
sctp:
usrsctp:
#
# time:
@@ -423,3 +421,17 @@ sctp:
# handover:
# duration: 500
time:
#
# metrics:
#
# <Metrics Server>
#
# o Metrics Server(http://<any address>:9090)
# metrics:
# addr: 0.0.0.0
# port: 9090
#
metrics:
addr: 0.0.0.0
port: 9090

View File

@@ -65,6 +65,18 @@ logger:
# sbi:
# dev: eth0
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
addr:
@@ -75,9 +87,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -99,30 +108,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.14
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <List of avaiable Network Slice Instance(NSI)>
#
# o One NSI
@@ -110,6 +122,18 @@ logger:
# s_nssai:
# sst: 1
# sd: 009000
#
# o NSI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# nsi:
# addr: ::1
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
nssf:
sbi:
- addr: 127.0.0.14
@@ -156,9 +180,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -180,30 +201,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.13
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
pcf:
sbi:
- addr: 127.0.0.13
@@ -106,6 +118,18 @@ pcf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -116,9 +140,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -140,30 +161,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -28,9 +28,6 @@ pcrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -40,11 +37,6 @@ pcrf:
# o Prefer IPv4 instead of IPv6 for estabishing new GTP connections.
# prefer_ipv4: true
#
# o Legacy support for pre-release LTE 11 devices to do calling
# - Replace IPv4/v6 local addr field in AAR Media-Subcomponent AVP
# by 'any local port'
# no_ipv4v6_local_addr_in_packet_filter: true
#
parameter:
#
@@ -56,27 +48,3 @@ parameter:
# gnb: 64
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:

View File

@@ -38,6 +38,14 @@ logger:
# - addr: 127.0.0.3
# - addr: fd69:f21d:873c:fa::2
#
# o GTP-C Option (Default)
# - so_bindtodevice : NULL
#
# gtpc:
# addr: 127.0.0.3
# option:
# so_bindtodevice: vrf-blue
#
# <PFCP Server>
#
# o PFCP Server(127.0.0.3:8805, ::1:8805)
@@ -49,6 +57,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.3
# option:
# so_bindtodevice: vrf-blue
#
sgwc:
gtpc:
- addr: 127.0.0.3
@@ -109,9 +125,6 @@ sgwu:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -136,30 +149,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -35,6 +35,14 @@ logger:
# pfcp:
# - name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.6
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>
#
# o GTP-U Server(127.0.0.6:2152, [::1]:2152)
@@ -80,6 +88,14 @@ logger:
# - dev: ens3
# advertise: sgw1.epc.mnc001.mcc001.3gppnetwork.org
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.6
# option:
# so_bindtodevice: vrf-blue
#
sgwu:
pfcp:
- addr: 127.0.0.6
@@ -101,9 +117,6 @@ sgwc:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -125,30 +138,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.4
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <PFCP Server>
#
# o PFCP Server(127.0.0.4:8805, ::1:8805)
@@ -84,6 +96,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-C Server>
#
# o GTP-C Server(127.0.0.4:2123, [fd69:f21d:873c:fa::3]:2123)
@@ -98,6 +118,14 @@ logger:
# - addr: 127.0.0.4
# - addr: fd69:f21d:873c:fa::3
#
# o GTP-C Option (Default)
# - so_bindtodevice : NULL
#
# gtpc:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>>
#
# o GTP-U Server(127.0.0.4:2152, [::1]:2152)
@@ -109,6 +137,14 @@ logger:
# gtpu:
# name: localhost
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <Subnet for UE Pool>
#
# o IPv4 Pool
@@ -197,6 +233,19 @@ logger:
# - 127.0.0.1
# - ::1
#
# <CTF>
#
# o Gy interface parameters towards OCS.
# o enabled:
# o auto: Default. Use Gy only if OCS available among Diameter peers
# o yes: Use Gy always;
# reject subscribers if no OCS available among Diameter peers
# o no: Don't use Gy interface if there is an OCS available
#
# ctf:
# enabled: auto|yes|no
#
#
# <SMF Selection - 5G Core only>
# 1. SMF sends SmfInfo(S-NSSAI, DNN, TAI) to the NRF
# 2. NRF responds to AMF with SmfInfo during NF-Discovery.
@@ -325,7 +374,7 @@ logger:
# mcc: 901
# mnc: 70
# tac: 99
#
#
smf:
sbi:
@@ -349,6 +398,8 @@ smf:
- 2001:4860:4860::8888
- 2001:4860:4860::8844
mtu: 1400
ctf:
enabled: auto
freeDiameter: @sysconfdir@/freeDiameter/smf.conf
#
@@ -377,6 +428,18 @@ smf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -390,7 +453,7 @@ nrf:
# <PFCP Client>>
#
# o PFCP Client(127.0.0.7:8805)
#
#
# pfcp:
# addr: 127.0.0.7
#
@@ -443,9 +506,6 @@ upf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -458,6 +518,10 @@ upf:
# o Disable selection of UPF PFCP in Round-Robin manner
# no_pfcp_rr_select: true
#
# o Legacy support for pre-release LTE 11 devices
# - Omits adding local address in packet filters for compatibility
# no_ipv4v6_local_addr_in_packet_filter: true
#
parameter:
#
@@ -470,30 +534,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#
@@ -523,3 +563,17 @@ pool:
# handover:
# duration: 500
time:
#
# metrics:
#
# <Metrics Server>
#
# o Metrics Server(http://<any address>:9090)
# metrics:
# addr: 0.0.0.0
# port: 9090
#
metrics:
addr: 0.0.0.0
port: 9090

View File

@@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.12
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
udm:
sbi:
- addr: 127.0.0.12
@@ -104,6 +116,18 @@ udm:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -114,9 +138,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -138,30 +159,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.20
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
udr:
sbi:
- addr: 127.0.0.20
@@ -106,6 +118,18 @@ udr:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@@ -116,9 +140,6 @@ nrf:
#
# parameter:
#
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true
#
@@ -140,30 +161,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -35,6 +35,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.7
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>>
#
# o GTP-U Server(127.0.0.7:2152, [::1]:2152)
@@ -80,6 +88,14 @@ logger:
# - dev: ens3
# advertise: upf1.5gc.mnc001.mcc001.3gppnetwork.org
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.7
# option:
# so_bindtodevice: vrf-blue
#
# <Subnet for UE network>
#
# Note that you need to setup your UE network using TUN device.
@@ -196,30 +212,6 @@ parameter:
#
max:
#
# pool:
#
# o The default memory pool size was set assuming 1024 UEs.
# To connect more UEs, you need to increase the size further.
#
# - Pool-size 128 => 65536 Number
# - Pool-size 256 => 16384 Number
# - Pool-size 512 => 4096 Number
# - Pool-size 1024 => 1024 Number
# - Pool-size 2048 => 512 Number
# - Pool-size 8192 => 128 Number
# - Pool-size 1024*1024 => 8 Number
#
# 128: 65536
# 256: 16384
# 512: 4096
# 1024: 1024
# 2048: 512
# 8192: 128
# big: 8
#
pool:
#
# time:
#

View File

@@ -4,3 +4,6 @@ Name=ogstun
[Network]
Address=10.45.0.1/16
Address=2001:db8:cafe::1/48
[Link]
RequiredForOnline=false

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS AMF Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS AUSF Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS MME Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS NSSF Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS SGW-C Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS SGW-U Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,7 +1,6 @@
[Unit]
Description=Open5GS SMF Daemon
After=networking.service
Requires=systemd-networkd.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,6 +1,6 @@
[Unit]
Description=Open5GS UDM Daemon
After=networking.service
After=network-online.target
[Service]
Type=simple

View File

@@ -1,7 +1,7 @@
[Unit]
Description=Open5GS UPF Daemon
After=networking.service
Requires=systemd-networkd.service
After=network-online.target systemd-networkd.service
Wants=systemd-networkd.service
[Service]
Type=simple

114
debian/changelog vendored
View File

@@ -1,3 +1,117 @@
open5gs (2.4.8) unstable; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 12 Jun 2022 16:28:51 +0900
open5gs (2.4.8~jammy) jammy; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 12 Jun 2022 16:27:13 +0900
open5gs (2.4.8~focal) focal; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 12 Jun 2022 16:23:05 +0900
open5gs (2.4.8~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 12 Jun 2022 16:22:04 +0900
open5gs (2.4.8~impish) impish; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 12 Jun 2022 16:19:27 +0900
open5gs (2.4.7) unstable; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 21 May 2022 19:20:07 +0900
open5gs (2.4.7~jammy) jammy; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 21 May 2022 19:19:10 +0900
open5gs (2.4.7~focal) focal; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 21 May 2022 19:18:11 +0900
open5gs (2.4.7~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 21 May 2022 19:17:08 +0900
open5gs (2.4.7~impish) impish; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 21 May 2022 19:14:58 +0900
open5gs (2.4.6) unstable; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Tue, 17 May 2022 22:41:32 +0900
open5gs (2.4.6~jammy) jammy; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Tue, 17 May 2022 22:40:16 +0900
open5gs (2.4.6~focal) focal; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Tue, 17 May 2022 22:38:38 +0900
open5gs (2.4.6~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Tue, 17 May 2022 22:37:22 +0900
open5gs (2.4.6~impish) impish; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Tue, 17 May 2022 22:34:40 +0900
open5gs (2.4.5) unstable; urgency=medium
* GTP-1C(GGSN) provided by sysmocom
-- Sukchan Lee <acetcom@gmail.com> Sun, 27 Mar 2022 18:41:04 +0900
open5gs (2.4.5~focal) focal; urgency=medium
* GTP-1C(GGSN) provided by sysmocom
-- Sukchan Lee <acetcom@gmail.com> Sun, 27 Mar 2022 18:40:06 +0900
open5gs (2.4.5~bionic) bionic; urgency=medium
* GTP-1C(GGSN) provided by sysmocom
-- Sukchan Lee <acetcom@gmail.com> Sun, 27 Mar 2022 18:38:55 +0900
open5gs (2.4.5~impish) impish; urgency=medium
* GTP-1C(GGSN) provided by sysmocom
-- Sukchan Lee <acetcom@gmail.com> Sun, 27 Mar 2022 18:37:40 +0900
open5gs (2.4.4) unstable; urgency=medium
* Fixed Memory leak

View File

@@ -67,7 +67,7 @@ services:
volumes:
- home:/home/${USER}
- ${HOME}:/mnt
- /tmp/.X11-unix:/tmp/.X11-unix
# - /tmp/.X11-unix:/tmp/.X11-unix
# - /etc/localtime:/etc/localtime:ro
# - /usr/share/zoneinfo/Europe/Helsinki:/etc/localtime:ro
hostname: open5gs-dev

View File

@@ -73,7 +73,7 @@ With the exception of the SMF and UPF, all config files for the 5G SA core funct
#### Ubuntu
*Ubuntu* makes it easy to install Open5GS as shown below,
*Ubuntu* makes it easy to install Open5GS as shown below.
```bash
$ sudo apt update
@@ -112,6 +112,7 @@ https://download.opensuse.org/repositories/home:/acetcom:/open5gs:/latest/xUbunt
https://download.opensuse.org/repositories/home:/acetcom:/open5gs:/latest/xUbuntu_20.10/
https://download.opensuse.org/repositories/home:/acetcom:/open5gs:/latest/xUbuntu_21.04/
https://download.opensuse.org/repositories/home:/acetcom:/open5gs:/latest/xUbuntu_21.10/
https://download.opensuse.org/repositories/home:/acetcom:/open5gs:/latest/xUbuntu_22.04/
```
#### openSUSE
@@ -149,6 +150,7 @@ https://download.opensuse.org/repositories/network:/osmocom:/nightly/xUbuntu_20.
https://download.opensuse.org/repositories/network:/osmocom:/nightly/xUbuntu_20.10/
https://download.opensuse.org/repositories/network:/osmocom:/nightly/xUbuntu_21.04/
https://download.opensuse.org/repositories/network:/osmocom:/nightly/xUbuntu_21.10/
https://download.opensuse.org/repositories/network:/osmocom:/nightly/xUbuntu_22.04/
```

View File

@@ -210,7 +210,6 @@ If you modify the config files while Open5GS daemons are running, please restart
---
```bash
$ cd install/bin/
$ ./install/bin/open5gs-mmed
Open5GS daemon v2.1.0

View File

@@ -10,6 +10,8 @@ If you have tested radio hardware from a vendor not listed with Open5GS, please
### Commercial 5G
---
* Airspan 5G OpenRange vCU + Airspan 5G OpenRange vDU + Airspan 5G OpenRANGE06 AirVelocity 2700 RU
* Airspan AirSpeed 2900
* Airspan AirStrand 2200
* LIONS RANathon O-CU and O-DU + RANathon RS8601 Indoor O-RU + RANathon XG8600 Fronthaul Gateway
* NOKIA AEQE (SW: 5G20A)
* NOKIA AEQD (SW: 5G20A)
@@ -40,6 +42,8 @@ If you have tested radio hardware from a vendor not listed with Open5GS, please
* Nokia FW2PC BC28 Flexi Zone G2 Outdoor Micro FDD LTE 700 MHz High Power
* Nokia FWH1 B38 Flexi Zone Outdoor Micro TD LTE 2600 MHz
* Nokia FRGY Flexi BTS BBU with Nokia FRCG RRU Band 5 850Mhz FDD 40W. Version 16.1A to 19.0
* Nokia FW2FA Flexi Zone Mini-Macro Outdoor BTS, 2x20w Band 39
* Nokia FWGR Flexi Zone Mini-Macro Outdoor BTS, 2x20w Band 1
* Ruckus Q710 and Q910
### 4G/5G Software Stacks + SDRs

View File

@@ -3,10 +3,10 @@ title: CentOS
head_inline: "<style> .blue { color: blue; } </style>"
---
This guide is based on **CentOS 8** Distribution.
This guide is based on **CentOS Stream 8** Distribution.
{: .blue}
## Install **CentOS 8** from Vagrant box (optional)
## Install **CentOS Stream 8** from Vagrant box (optional)
---
Vagrant provides a simple way to create and deploy Virtual Machines from
pre-built images using VirtualBox, libvirt, or VMWare as a hypervisor engine.
@@ -20,13 +20,13 @@ The instructions to install Vagrant are provided at
[vagrantup.com](https://www.vagrantup.com/).
### Create a CentOS 8 Virtual Machine using Vagrant
### Create a CentOS Stream 8 Virtual Machine using Vagrant
---
Use the supplied `Vagrantfile` in the `vagrant` directory to create the
virtual machine.
Note that this Vagrantfile is identical to the base CentOS 8 box, with
Note that this Vagrantfile is identical to the base CentOS Stream 8 box, with
the exception that the amount of virtual memory has been increased to 1GB:
```bash
@@ -37,7 +37,7 @@ vagrant up --provider virtualbox
### Log into the newly created CentOS VM
---
Use SSH to log into the CentOS 8 VM:
Use SSH to log into the CentOS Stream 8 VM:
```bash
vagrant ssh
@@ -45,20 +45,20 @@ vagrant ssh
Note that the Open5GS source is *not* copied into the VM. The instructions
below provide the step by step instructions for setting up Open5GS for
either a bare metal or virtual CentOS 8 system.
either a bare metal or virtual CentOS Stream 8 system.
The rest of the commands below are performed inside the CentOS VM as the
user 'vagrant', or on your bare metal CentOS 8 system as any normal user.
user 'vagrant', or on your bare metal CentOS Stream 8 system as any normal user.
## Install prerequisite packages to build and run Open5GS
---
### Enable CentOS 8 PowerTools repository
### Enable CentOS Stream 8 PowerTools repository
---
```bash
$ sudo dnf install 'dnf-command(config-manager)'
$ sudo dnf config-manager --set-enabled PowerTools
$ sudo dnf config-manager --set-enabled powertools
```
### Enable the Extra Packages for Enterprise Linux
@@ -86,13 +86,13 @@ $ sudo dnf config-manager --set-enabled elrepo-testing
Create a repository file to install the MongoDB packages:
```bash
$ sudo sh -c 'cat << EOF > /etc/yum.repos.d/mongodb-org-3.4.repo
[mongodb-org-3.4]
$ sudo sh -c 'cat << EOF > /etc/yum.repos.d/mongodb-org-3.6.repo
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/3.4/x86_64/
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
EOF'
```
@@ -105,20 +105,13 @@ $ sudo dnf -y install mongodb-org
### Install the dependencies for building the source code.
---
Open5GS requires several packages which are not installed by default in
a base CentOS 8 installation.
a base CentOS Stream 8 installation.
```bash
$ sudo dnf install python3 meson ninja-build gcc gcc-c++ flex bison git lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel openssl-devel cyrus-sasl-devel libyaml-devel mongo-c-driver-devel libmicrohttpd-devel libcurl-devel libnghttp2-devel libtalloc-devel
```
### Install the SCTP kernel module in kernel-modules-extra.
---
```bash
$ sudo dnf install kernel-modules-extra
```
### Install iproute IP interface tools.
---
@@ -126,6 +119,15 @@ $ sudo dnf install kernel-modules-extra
$ sudo dnf install iproute
```
### Install the SCTP kernel module in kernel-modules-extra.
---
```bash
$ sudo dnf install kernel-modules-extra
$ sudo rm /etc/modprobe.d/sctp-blacklist.conf
$ sudo rm /etc/modprobe.d/sctp_diag-blacklist.conf
```
### Update all installed packages to the latest versions.
---
@@ -141,11 +143,27 @@ after this step to ensure that you are running this new kernel version.
This is important when you try to load the SCTP kernel module later.
```bash
[vm] $ sudo reboot
[host] $ vagrant halt
[host] $ vagrant up --provider virtualbox
[host] $ # ssh back into the VM after it reboots...
[host] $ vagrant ssh
```
### Check the SCTP kernel module
---
Open5GS requires the Linux SCTP kernel module to be loaded in the kernel.
In the CentOS Stream 8 Vagrant box SCTP is not loaded into the kernel automatically
so must be installed as follows:
```bash
$ checksctp
SCTP supported
$ sudo modprobe sctp
$ # Check that SCTP was loaded successfully:
$ sudo dmesg | grep sctp
[ 639.971360] sctp: Hash tables configured (bind 256/256)
```
## Build Open5GS from Source
---
@@ -252,19 +270,6 @@ to configure the TUN device as follows:
`$ sudo ./misc/netconf.sh`
{: .notice--info}
### Install the SCTP kernel module
---
Open5GS requires the Linux SCTP kernel module to be loaded in the kernel.
In the CentOS 8 Vagrant box SCTP is not loaded into the kernel automatically
so must be installed as follows:
```bash
$ sudo modprobe sctp
$ # Check that SCTP was loaded successfully:
$ sudo dmesg | grep sctp
[ 639.971360] sctp: Hash tables configured (bind 256/256)
```
## Testing Open5GS
---

View File

@@ -0,0 +1,134 @@
---
title: Metrics with Prometheus
---
#### 0. Introduction
This tutorial explains how to export open5gs metrics to Prometheus, which can in
turn be used to visualize or export them to other systems such as Grafana or
StatsD.
When this method is used, any open5gs program exporting metrics becomes a
Prometheus server, which is basically an HTTP server serving Prometheus data to
the Prometheus scrapper.
Note: Only open5gs-smfd supports exporting metrics so far, though other may
hopefully follow soon.
#### 1. Enable Prometheus support during build
Open5GS programs use a generic internal API available in libogsmetrics. This
library implements the API based on configuration passed during open5gs build
time. By default, the library will be built using the `void` implementation,
which is basically a NO-OP implementation.
In order to use the Prometheus, the `prometheus` metrics implementation needs to
be selected at build time:
```
meson configure -Dmetrics_impl=prometheus build
```
This will enable building the implementation under lib/metrics/prometheus/,
which uses:
* prometheus-client-c project (libprom): To generate the Prometheus expected
output format of the metrics
* libmicrohttpd: To server the content generated by libprom as an HTTP server
The `prometheus-client-c` project is not currently well maintained, and uses a
weird mixture of build systems, which makes it difficult to make it available in
most Linux distributions. As a result, a fork of the project is available under
Open5GS GitHub namespace, with an extra patch applied making it possible to
include it as a subproject, which will be fetched and built automatically when
building the prometheus libmetrics implementation.
#### 2. Configuring for runtime
By default the created Prometheus HTTP server will be listening on `0.0.0.0`
port `9090`.
This can be configured under the following config file options:
```
#
# metrics:
#
# <Metrics Server>
#
# o Metrics Server(http://<any address>:9090)
# metrics:
# addr: 0.0.0.0
# port: 9090
#
metrics:
addr: 0.0.0.0
port: 9090
```
Note: You may want to change the default IP address or port if you are running
the Prometheus scrapper in the same host, since it will also spawn its own
Prometheus server also in port 9090, which will collide.
#### 3. Manual visualization
Simply open the web browser at the following URL (changing IP address and port
as configured in previous section):
```
http://127.0.0.1:9090/metrics
```
Note: URL `metrics/` (with a slash at the end) will not work.
You should see some output similar to this one below:
```
# HELP ues_active Active User Equipments
# TYPE ues_active gauge
ues_active 2
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024
# HELP process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes.
# TYPE process_virtual_memory_max_bytes gauge
process_virtual_memory_max_bytes -1
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total gauge
process_cpu_seconds_total 0
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 3156643840
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 402433
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 23
```
#### 3. Integration with Prometheus scrapper
Sample Prometheus scrapper configuration (`~/prometheus.yml`):
```
global:
scrape_interval: 10s
scrape_configs:
- job_name: open5gs-smfd
static_configs:
- targets: ["192.168.1.140:9091"]
```
Where `192.168.1.140:9091` is the IP address and port where `open5gs-smfd` is
serving its metrics, as configured in above sections.
The Prometheus scrapper can be easily started from a docker container:
```
docker run -p 9090:9090 -v /prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
```
Then open your browser to be able to visualize the data: `http://localhost:9090/graph`

View File

@@ -13,6 +13,7 @@ head_inline: "<style> ul { padding-bottom: 1em; } </style>"
- [Your First LTE](tutorial/01-your-first-lte)
- [VoLTE Setup with Kamailio IMS and Open5GS](tutorial/02-VoLTE-setup)
- [Dockerized VoLTE Setup](tutorial/03-VoLTE-dockerized)
- [Metrics with Prometheus](tutorial/04-metrics-prometheus)
- Troubleshooting
- [Simple Issues](troubleshoot/01-simple-issues)
@@ -26,10 +27,10 @@ head_inline: "<style> ul { padding-bottom: 1em; } </style>"
- [MacOSX(Intel)](platform/06-macosx-intel)
- [FreeBSD](platform/07-freebsd)
- [Alpine](platform/08-alpine)
- Hardware Specific Notes
- [eNodeBs/gNodeBs tested on Open5GS](hardware/01-genodebs)
- @infinitydon
- [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)
@@ -46,3 +47,4 @@ head_inline: "<style> ul { padding-bottom: 1em; } </style>"
- [Open5GS EPC & OpenAirInterface UE/RAN Sample configuration](https://github.com/s5uishida/open5gs_epc_oai_sample_config)
- [Open5GS 5GC & UERANSIM UE/RAN Sample Configuration](https://github.com/s5uishida/open5gs_5gc_ueransim_sample_config)
- [Open5GS & UERANSIM - Select nearby UPF according to the connected gNodeB](https://github.com/s5uishida/open5gs_5gc_ueransim_nearby_upf_sample_config)
- [VoLTE and SMS Configuration for docker_open5gs](https://github.com/s5uishida/docker_open5gs_volte_sms_config)

View File

@@ -0,0 +1,19 @@
---
title: "v2.4.4 - Memory leak fixed"
date: 2022-02-01 15:09:00 +0900
categories:
- Release
tags:
- News
- Release
head_inline: "<style> ul { padding-bottom: 1em; } .blue { color: blue; }</style>"
---
#### Bug Fixes
- [NRF] Fixed the crash if reqNFInstanceId does not exist in Subscription ([#1347](https://github.com/open5gs/open5gs/issues/1347)) -- [ajimenezsa](https://github.com/ajimenezsa)
- [ALL] Memory leak fixed ([#1282](https://github.com/open5gs/open5gs/issues/1282)) -- [bluehat-f](https://github.com/bluehat-f), [micjerry](https://github.com/micjerry)
- [SMF] Fixed SMF crash if TransportLayerAddress in GTPTunnel does not exist ([#1341](https://github.com/open5gs/open5gs/issues/1341)) -- [modyngs](https://github.com/modyngs)
- [SBI] Remove one octet length in FQDN ([#1333](https://github.com/open5gs/open5gs/issues/1333)) -- [ajimenezsa](https://github.com/ajimenezsa)
Download -- [v2.4.4.tar.gz](https://github.com/open5gs/open5gs/archive/v2.4.4.tar.gz)
{: .notice--info}

View File

@@ -0,0 +1,42 @@
---
title: "v2.4.5 - GTP-1C(GGSN) provided by sysmocom"
date: 2022-03-27 19:32:00 +0900
categories:
- Release
tags:
- News
- Release
head_inline: "<style> ul { padding-bottom: 1em; } .blue { color: blue; }</style>"
---
#### New Features
- [SMF] Introduced Gn interface(GTPv1C) Support to SMF provided [sysmocom](https://sysmocom.de) -- [pespin](https://github.com/pespin)
#### Enhancements
- [SMF] Remove T_RELEASE_HOLDING timer -- [72ecd1c](https://github.com/open5gs/open5gs/commit/72ecd1c0052a55d8aefb645eb2c3e7c64057caae)
- [MME] Refactor to check a piggybacked ESM -- [bf77318](https://github.com/open5gs/open5gs/commit/bf773186026c9847a2aff0035d91949a1b098d14)
- [CORE] Added APIs to manage NTP 32-bit timestamps ([#1439](https://github.com/open5gs/open5gs/pull/1439)) -- [pespin](https://github.com/pespin)
- [GTP] Supprt binding socket to device/Improve socket configuration ([#1404](https://github.com/open5gs/open5gs/pull/1404)) -- [pespin](https://github.com/pespin)
- [ASN] Applied the NGAP modification of both [mouse07410/asn1c#89](https://github.com/mouse07410/asn1c/pull/89) and [mouse07410/asn1c#90](https://github.com/mouse07410/asn1c/pull/90) -- [nkout](https://github.com/nkout)
- [SMF] Support PCO protocol ID PAP(0xc023) ([#1357](https://github.com/open5gs/open5gs/issues/1357)) -- [pespin](https://github.com/pespin)
- [ALL] Refined systemd sequencing ([#1366](https://github.com/open5gs/open5gs/pull/1366), [#1368](https://github.com/open5gs/open5gs/pull/1368)) -- [matt9j](https://github.com/matt9j)
#### Security Updates
- [UPF] Check if Source IP address is spoofing ([#1354](https://github.com/open5gs/open5gs/issues/1354), [#1355](https://github.com/open5gs/open5gs/issues/1355)) -- [pespin](https://github.com/pespin)
#### Bug Fixes
- [AMF] Fixed the Slice/DNN selection method ([#1438](https://github.com/open5gs/open5gs/issues/1438), [#1440](https://github.com/open5gs/open5gs/issues/1440)) -- [dcandal-gti](https://github.com/dcandal-gti)
- [ALL] Use talloc memory pool in PKBUF ([#1353](https://github.com/open5gs/open5gs/issues/1353), [#1431](https://github.com/open5gs/open5gs/issues/1431)) -- [raphaelsander](https://github.com/raphaelsander)
- [SMF] Exception handling for APN duplicate check ([#1431](https://github.com/open5gs/open5gs/issues/1431)) -- [raphaelsander](https://github.com/raphaelsander)
- [SBI] Need to increase NF reference count -- [ed34444e](https://github.com/open5gs/open5gs/commit/ed3444eef5e9e57705645b500dbd6c5af453703f)
- [CORE] Initialize struct epoll_event ([#1399](https://github.com/open5gs/open5gs/issues/1399)) -- [pespin](https://github.com/pespin)
- [SMF/PCRF] Fixed prefix length in Gx CCR Framed-IPv6-Prefix AVP ([#1396](https://github.com/open5gs/open5gs/pull/1396), [#1398](https://github.com/open5gs/open5gs/pull/1398)) -- [herlesupreeth](https://github.com/herlesupreeth)
- [SMF/PCRF] Fixed packet fileter for pre rel11 LTE devices ([#1393](https://github.com/open5gs/open5gs/pull/1393)) -- [herlesupreeth](https://github.com/herlesupreeth)
- [SMF] Fixed an incorrect GTP cause with a changed APN type(IPv4v6->IPv4/IPv6) ([#1360](https://github.com/open5gs/open5gs/issues/1360)) -- [pespin](https://github.com/pespin)
- [ALL] Fixed the timezone string converter ([#1376](https://github.com/open5gs/open5gs/issues/1376)) -- [modyngs](https://github.com/modyngs)
- [SMF] Added DNS servers to PCO IPCP only if UE requested ([#1358](https://github.com/open5gs/open5gs/issues/1358)) -- [pespin](https://github.com/pespin)
- [SBI] Remove Accept-Encoding(gzip) in HTTP2-Client -- [ffcd92c](https://github.com/open5gs/open5gs/commit/ffcd92c2f3b6547ae8d159b195ffc0592ad0f3e9)
- [SBI] Fixed NFs crash if no mandotory item such like a version in NFService ([#1350](https://github.com/open5gs/open5gs/issues/1350)) -- [ajimenezsa](https://github.com/ajimenezsa)
Download -- [v2.4.5.tar.gz](https://github.com/open5gs/open5gs/archive/v2.4.5.tar.gz)
{: .notice--info}

View File

@@ -0,0 +1,45 @@
---
title: "v2.4.7 - Gy interface provided by sysmocom"
date: 2022-05-21 19:42:00 +0900
categories:
- Release
tags:
- News
- Release
head_inline: "<style> ul { padding-bottom: 1em; } .blue { color: blue; }</style>"
---
#### New Features
- [SMF] Introduced Gy interface Support provided by [sysmocom](https://sysmocom.de) -- [pespin](https://github.com/pespin)
- [GTP] X2 Handover with SGW relocation ([#1367](https://github.com/open5gs/open5gs/issues/1367), [#1459](https://github.com/open5gs/open5gs/issues/1459)) -- [pespin](https://github.com/pespin), [cbrasho](https://github.com/cbrasho)
#### Enhancements
- [GY] Clarify use of Reporting-Request and set it to FINAL in TERMINATION_REQ ([#1552](https://github.com/open5gs/open5gs/pull/1552)) -- [pespin](https://github.com/pespin)
- [SBI] Change handling of SessionManagementSubscriptionData as an array ([#1551](https://github.com/open5gs/open5gs/pull/1551)) -- [bmeglicit](https://github.com/bmeglicit)
- [PFCP] Support Multi-CP with One-UP ([c6c8dc1](https://github.com/open5gs/open5gs/commit/c6c8dc1256c304aea1fc44cd70fbaeb290f31ad3))
- [SMF] Use Only One PFCP Session Modification Message in the ViNR([e0a487f](https://github.com/open5gs/open5gs/commit/e0a487f479b7d916044d6595228de6211d548656))
- [SMF] Parallelize Gx+Gy CCR Initial ([#1491](https://github.com/open5gs/open5gs/pull/1491)) -- [pespin](https://github.com/pespin)
- [SMF] Integrate Session Setup Cycle into GSM State Machine ([#1489](https://github.com/open5gs/open5gs/pull/1489)) -- [pespin](https://github.com/pespin)
- [CX] Functionality for send SMS with using IMS service ([#1477](https://github.com/open5gs/open5gs/pull/1477)) -- [EugeneBogush](https://github.com/EugeneBogush)
- [MEM] Improve data-path performance using talloc_pool() -- ([e213f65](https://github.com/open5gs/open5gs/commit/e213f654060b7b9f2bae11420c5175e876cf006e))
- [TEST] Automatic CI for github PRs ([#1454](https://github.com/open5gs/open5gs/issues/1454)) -- [pespin](https://github.com/pespin)
- [DB] Add/update current IMEISV of UE in subscriber profile ([#1464](https://github.com/open5gs/open5gs/pull/1464)) -- [EugeneBogush](https://github.com/EugeneBogush)
#### Bug Fixes
- [CORE] Fixed the linked-list BUG ([#1187](https://github.com/open5gs/open5gs/issues/1187)) -- [Vomvas](https://github.com/Vomvas)
- [SMF] Prevent concurrent access to ogs_pool allocating smf_event ([#1546](https://github.com/open5gs/open5gs/issues/1546)) -- [pespin](https://github.com/pespin)
- [DIAMETER] Fix AN-Trusted AVP sent in CCR ([#1542](https://github.com/open5gs/open5gs/pull/1542)) -- [herlesupreeth](https://github.com/herlesupreeth)
- [PFCP] Fixed incorrect memcpy usage ([#1531](https://github.com/open5gs/open5gs/issues/1531)) -- [pespin](https://github.com/pespin)
- [AMF] Fixed the bug Not Sending NG RESET Acknowledge ([#1525](https://github.com/open5gs/open5gs/issues/1525)) -- [mcatalancid](https://github.com/mcatalancid)
- [IPv6] IPv6 RS/RA with QFI Extended Header ([#1506](https://github.com/open5gs/open5gs/issues/1506)) -- [irazairspan](https://github.com/irazairspan)
- [SBI] cJSON v1.7.7 to v1.7.15 to solve HTTP2 request with incorrect payload ([#1503](https://github.com/open5gs/open5gs/issues/1503)) -- [bmeglicit](https://github.com/bmeglicit)
- [GTP] Handling multiple bearer message ([#1498](https://github.com/open5gs/open5gs/issues/1498)) -- [cbrasho](https://github.com/cbrasho)
- [MME] SCTP Crash when eNB, SGW-U and UPF are going down ([#1497](https://github.com/open5gs/open5gs/pull/1497)) -- [spencersevilla](https://github.com/spencersevilla)
- [SBI] fixed HTTP2 header values is 0 ([#1488](https://github.com/open5gs/open5gs/issues/1488)) -- [bmeglicit](https://github.com/bmeglicit)
- [MME] Send EMM Cause when Attach Request type is not same as HSS Network-Access-Mode ([#1484](https://github.com/open5gs/open5gs/pull/1484)) -- [herlesupreeth](https://github.com/herlesupreeth)
- [GX] Prevent sending Gx messages to non-PCRF Diameter peers ([#1468](https://github.com/open5gs/open5gs/pull/1468)) -- [pespin](https://github.com/pespin)
- [AMF] AMF crashes when requesting a PDU session for a S-NSSAI with an SST when the network is configured with multiple S-NSSAIs with the same SST ([#1440](https://github.com/open5gs/open5gs/issues/1440)) -- [dcandal-gti](https://github.com/dcandal-gti)
Download -- [v2.4.7.tar.gz](https://github.com/open5gs/open5gs/archive/v2.4.7.tar.gz)
{: .notice--info}

View File

@@ -0,0 +1,31 @@
---
title: "v2.4.8 - Upgrade PFCP to v16.9.1"
date: 2022-06-12 16:35:00 +0900
categories:
- Release
tags:
- News
- Release
head_inline: "<style> ul { padding-bottom: 1em; } .blue { color: blue; }</style>"
---
#### New Features
- [Metrics] Initial metrics support based on Prometheus ([#1571](https://github.com/open5gs/open5gs/pull/1571)) -- [pespin](https://github.com/pespin)
#### Enhancements
- [PFCP] Upgrade PFCP to v16.9.1 [1235317](https://github.com/open5gs/open5gs/commit/12353178fb7c15a5c78035e19501412af9c76ad0)
- [AMF] Added support for SUCI prtection schemes A and B( ([#1589](https://github.com/open5gs/open5gs/pull/1589)) -- [bmeglicit](https://github.com/bmeglicit)
- [NRF] Don't abort if there are too many registered NF instances ([#1579](https://github.com/open5gs/open5gs/pull/1579)) -- [mitmitmitm](https://github.com/mitmitmitm)
- [SGW-C] Consider if SMF/PGW GTPv2-C address changed ([#1560](https://github.com/open5gs/open5gs/issues/1560)) -- [pespin](https://github.com/pespin)
- [CLI] Added four addtional commands in dbctl ([#1562](https://github.com/open5gs/open5gs/pull/1562)) -- [mcatalancid](https://github.com/mcatalancid)
- [GY] Gy+PFCP improvements ([#1555](https://github.com/open5gs/open5gs/pull/1555)) -- [pespin](https://github.com/pespin)
#### Bug Fixes
- [AMF] Added to handle an invalid RI(Routing Indicator) ([#1570](https://github.com/open5gs/open5gs/issues/1570)) -- [ray28850101](https://github.com/ray28850101)
- [SBI] Re-enabling HTTP/1.1 ([#1254](https://github.com/open5gs/open5gs/issues/1254)) -- [hidingturtle](https://github.com/hidingturtle), [22username2022](https://github.com/22username2022)
- [GTP] GTP-U address does not change when gNB with IPv6-only changes
([#1515](https://github.com/open5gs/open5gs/issues/1515), [#1586](https://github.com/open5gs/open5gs/issues/1586)) -- [irazairspan](https://github.com/irazairspan), [dmartyushev](https://github.com/dmartyushev)
Download -- [v2.4.8.tar.gz](https://github.com/open5gs/open5gs/archive/v2.4.8.tar.gz)
{: .notice--info}

View File

@@ -10,7 +10,7 @@
#
PACKAGE="open5gs"
VERSION="2.4.3"
VERSION="2.4.7"
print_status() {
echo

View File

@@ -20,10 +20,12 @@ libapp_sources = files('''
ogs-yaml.h
ogs-context.h
ogs-config.h
ogs-init.h
ogs-yaml.c
ogs-context.c
ogs-config.c
ogs-init.c
'''.split())

View File

@@ -28,6 +28,7 @@ extern int __ogs_app_domain;
#include "app/ogs-yaml.h"
#include "app/ogs-context.h"
#include "app/ogs-config.h"
#include "app/ogs-init.h"
#undef OGS_APP_INSIDE

110
lib/app/ogs-config.c Normal file
View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "ogs-app.h"
int ogs_app_config_parse_sockopt(
ogs_yaml_iter_t *parent, ogs_sockopt_t *option)
{
ogs_yaml_iter_t sockopt_iter;
ogs_assert(parent);
ogs_assert(option);
ogs_sockopt_init(option);
ogs_yaml_iter_recurse(parent, &sockopt_iter);
while (ogs_yaml_iter_next(&sockopt_iter)) {
const char *sockopt_key = ogs_yaml_iter_key(&sockopt_iter);
ogs_assert(sockopt_key);
if (!strcmp(sockopt_key, "sctp")) {
ogs_yaml_iter_t sctp_iter;
ogs_yaml_iter_recurse(&sockopt_iter, &sctp_iter);
while (ogs_yaml_iter_next(&sctp_iter)) {
const char *sctp_key = ogs_yaml_iter_key(&sctp_iter);
ogs_assert(sctp_key);
if (!strcmp(sctp_key, "spp_hbinterval")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.spp_hbinterval = atoi(v);
} else if (!strcmp(sctp_key, "spp_sackdelay")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.spp_sackdelay = atoi(v);
} else if (!strcmp(sctp_key, "srto_initial")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_initial = atoi(v);
} else if (!strcmp(sctp_key, "srto_min")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_min = atoi(v);
} else if (!strcmp(sctp_key, "srto_max")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_max = atoi(v);
} else if (!strcmp(sctp_key, "sinit_num_ostreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_num_ostreams = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_instreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_instreams = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_attempts")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_attempts = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_init_timeo")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_init_timeo = atoi(v);
} else {
ogs_error("unknown key `%s`", sctp_key);
return OGS_ERROR;
}
}
} else if (!strcmp(sockopt_key, "sctp_nodelay")) {
option->sctp_nodelay = ogs_yaml_iter_bool(&sockopt_iter);
} else if (!strcmp(sockopt_key, "tcp_nodelay")) {
option->tcp_nodelay = ogs_yaml_iter_bool(&sockopt_iter);
} else if (!strcmp(sockopt_key, "so_linger")) {
ogs_yaml_iter_t so_linger_iter;
ogs_yaml_iter_recurse(&sockopt_iter, &so_linger_iter);
while (ogs_yaml_iter_next(&so_linger_iter)) {
const char *so_linger_key = ogs_yaml_iter_key(&so_linger_iter);
ogs_assert(so_linger_key);
if (!strcmp(so_linger_key, "l_onoff")) {
option->so_linger.l_onoff =
ogs_yaml_iter_bool(&so_linger_iter);
} else if (!strcmp(so_linger_key, "l_linger")) {
const char *v = ogs_yaml_iter_value(&so_linger_iter);
if (v) option->so_linger.l_linger = atoi(v);
} else {
ogs_error("unknown key `%s`", so_linger_key);
return OGS_ERROR;
}
}
} else if (!strcmp(sockopt_key, "so_bindtodevice")) {
option->so_bindtodevice = ogs_yaml_iter_value(&sockopt_iter);
} else {
ogs_error("unknown key `%s`", sockopt_key);
return OGS_ERROR;
}
}
return OGS_OK;
}

38
lib/app/ogs-config.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_APP_INSIDE) && !defined(OGS_APP_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_APP_CONFIG_H
#define OGS_APP_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
int ogs_app_config_parse_sockopt(
ogs_yaml_iter_t *parent, ogs_sockopt_t *sockopt);
#ifdef __cplusplus
}
#endif
#endif /* OGS_APP_CONFIG_H */

View File

@@ -226,9 +226,12 @@ static void app_context_prepare(void)
*/
self.time.handover.duration = ogs_time_from_msec(300);
/* Size of internal metrics pool (amount of ogs_metrics_spec_t) */
self.metrics.max_specs = 512;
regenerate_all_timer_duration();
}
static int app_context_validation(void)
{
if (self.parameter.no_ipv4 == 1 &&

View File

@@ -24,8 +24,6 @@
#ifndef OGS_APP_CONTEXT_H
#define OGS_APP_CONTEXT_H
#include "ogs-app.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -177,6 +175,10 @@ typedef struct ogs_app_context_s {
} handover;
} time;
struct metrics {
uint64_t max_specs;
} metrics;
} ogs_app_context_t;
int ogs_app_context_init(void);

View File

@@ -32,9 +32,6 @@ int ogs_app_initialize(
char *log_file;
char *log_level;
char *domain_mask;
bool enable_debug;
bool enable_trace;
} optarg;
ogs_core_initialize();

View File

@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-yaml.h"
#include "ogs-app.h"
void ogs_yaml_iter_init(ogs_yaml_iter_t *iter, yaml_document_t *document)
{

View File

@@ -26,8 +26,6 @@
#include <yaml.h>
#include "ogs-app.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -89,7 +89,7 @@ NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,
asn_enc_rval_t er = {0,0,0};
long native, value;
const asn_per_constraint_t *ct;
int inext = 0;
int inext = 0, range_bits = 1;
asn_INTEGER_enum_map_t key;
asn_INTEGER_enum_map_t *kf;
@@ -126,12 +126,12 @@ NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,
if(ct->flags & APC_EXTENSIBLE) {
if(per_put_few_bits(po, inext, 1))
ASN__ENCODE_FAILED;
if(inext) ct = 0;
if(inext) range_bits = 0;
} else if(inext) {
ASN__ENCODE_FAILED;
}
if(ct && ct->range_bits >= 0) {
if(range_bits && ct && ct->range_bits >= 0) {
if(per_put_few_bits(po, value, ct->range_bits))
ASN__ENCODE_FAILED;
ASN__ENCODED_OK(er);

View File

@@ -94,6 +94,14 @@ asn_enc_rval_t OPEN_TYPE_encode_aper(
const asn_TYPE_descriptor_t *type_descriptor,
const asn_per_constraints_t *constraints, const void *struct_ptr,
asn_per_outp_t *per_output);
int OPEN_TYPE_aper_is_unknown_type(
const asn_TYPE_descriptor_t *td,
void *sptr,
const asn_TYPE_member_t *elm);
asn_dec_rval_t OPEN_TYPE_aper_unknown_type_discard_bytes(
asn_per_data_t *pd);
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;

View File

@@ -117,3 +117,58 @@ OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
er.encoded = 0;
ASN__ENCODED_OK(er);
}
int OPEN_TYPE_aper_is_unknown_type(const asn_TYPE_descriptor_t *td, void *sptr, const asn_TYPE_member_t *elm) {
asn_type_selector_result_t selected;
if(!elm->type_selector) {
return 1;
}
else {
selected = elm->type_selector(td, sptr);
if(!selected.presence_index) {
return 1;
}
}
return 0;
}
asn_dec_rval_t
OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) {
#define ASN_DUMMY_BYTES 256
unsigned char dummy[ASN_DUMMY_BYTES], *dummy_ptr = NULL;
ssize_t bytes;
int repeat;
asn_dec_rval_t rv;
rv.consumed = 0;
rv.code = RC_FAIL;
do {
bytes = aper_get_length(pd, -1, -1, &repeat);
if (bytes > 10 * ASN_DUMMY_BYTES)
{
return rv;
}
else if (bytes > ASN_DUMMY_BYTES)
{
dummy_ptr = CALLOC(1, bytes);
if (!dummy_ptr)
return rv;
}
per_get_many_bits(pd, (dummy_ptr ? dummy_ptr : dummy), 0, bytes << 3);
if (dummy_ptr)
{
FREEMEM(dummy_ptr);
dummy_ptr = NULL;
}
} while (repeat);
rv.code = RC_OK;
return rv;
#undef ASN_DUMMY_BYTES
}

View File

@@ -151,10 +151,10 @@ UTF8String_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
static ssize_t
UTF8String__process(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
size_t length;
uint8_t *buf = st->buf;
uint8_t *end = buf + st->size;
uint32_t *dstend = dst + dstlen;
size_t length = 0;
uint8_t *buf = (st == NULL)? NULL : st->buf;
uint8_t *end = (buf == NULL)? NULL : buf + st->size;
uint32_t *dstend = (dst == NULL)? NULL : dst + dstlen;
for(length = 0; buf < end; length++) {
int ch = *buf;

View File

@@ -130,6 +130,11 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
if(elm->flags & ATF_OPEN_TYPE) {
if (OPEN_TYPE_aper_is_unknown_type(td, st, elm)) {
rv = OPEN_TYPE_aper_unknown_type_discard_bytes(pd);
FREEMEM(opres);
return rv;
}
rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
} else {
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,

View File

@@ -49420,7 +49420,7 @@ static asn_TYPE_member_t asn_MBR_NGAP_extensionValue_648[] = {
0,
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
#if 0
#if 0 /* modified by acetcom */
&asn_PER_memb_NGAP_OCTET_STRING_CONTAINING_PDUSessionResourceReleaseResponseTransfer__constr_47,
#else
0,

View File

@@ -1,15 +1,17 @@
Use mounse07410(vlm_master) git's fork for asn1c
commit dcf963c0e43196057a97feac16421fe79dc7d943 (HEAD -> vlm_master, origin/vlm_master, origin/HEAD)
Merge: b33a84f9 c35ebd33
Author: Mouse <mouse008@gmail.com>
Date: Sun Nov 1 08:58:12 2020 -0500
commit c098de2086633d2027f1d117092541d8482c1c96 (HEAD -> vlm_master, origin/vlm_master, origin/HEAD)
Author: Nikolaos Koutsianas <nkoutsianas@gmail.com>
Date: Fri Feb 25 13:18:01 2022 +0200
aper decoder can ignore unknown open types in a sequence and continue with next ones
===========================================
user@host ~/Documents/git/my$ \
git clone https://github.com/mouse07410/asn1c.git
user@host ~/Documents/git/my$ \
git checkout 8282f80bc89cc773f9432cde56398a36f2683511
git checkout git checkout c098de2086633d2027f1d117092541d8482c1c96
OR
@@ -175,24 +177,59 @@ Check common file
user@host ~/Documents/git/open5gs/lib/asn1c/common$ \
git diff asn_internal.h
diff --git a/lib/asn1c/common/asn_internal.h b/lib/asn1c/common/asn_internal.h
index 71397a62..0b673a46 100644
--- a/lib/asn1c/common/asn_internal.h
+++ b/lib/asn1c/common/asn_internal.h
@@ -34,18 +34,11 @@ extern "C" {
#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
int get_asn1c_environment_version(void); /* Run-time version */
diff -u asn_internal.h ~/asn_internal.h
--- asn_internal.h 2022-02-26 15:48:33.431509100 +0900
+++ /home/acetcom/asn_internal.h 2022-02-26 15:43:00.890972555 +0900
@@ -34,10 +34,53 @@
#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
int get_asn1c_environment_version(void); /* Run-time version */
+#if 0 /* modified by acetcom */
+#define CALLOC(nmemb, size) calloc(nmemb, size)
+#define MALLOC(size) malloc(size)
+#define REALLOC(oldptr, size) realloc(oldptr, size)
+#define FREEMEM(ptr) free(ptr)
#define CALLOC(nmemb, size) calloc(nmemb, size)
#define MALLOC(size) malloc(size)
#define REALLOC(oldptr, size) realloc(oldptr, size)
#define FREEMEM(ptr) free(ptr)
+#else
#include "ogs-core.h"
#define CALLOC(nmemb, size) ogs_calloc(nmemb, size)
#define MALLOC(size) ogs_malloc(size)
#define REALLOC(oldptr, size) ogs_realloc(oldptr, size)
#define FREEMEM(ptr) ogs_free(ptr)
+#include "ogs-core.h"
+
+static ogs_inline void *ogs_asn_malloc(size_t size, const char *file_line)
+{
+ void *ptr = ogs_malloc(size);
+ if (!ptr) {
+ ogs_fatal("asn_malloc() failed in `%s`", file_line);
+ ogs_assert_if_reached();
+ }
+
+ return ptr;
+}
+static ogs_inline void *ogs_asn_calloc(
+ size_t nmemb, size_t size, const char *file_line)
+{
+ void *ptr = ogs_calloc(nmemb, size);
+ if (!ptr) {
+ ogs_fatal("asn_calloc() failed in `%s`", file_line);
+ ogs_assert_if_reached();
+ }
+
+ return ptr;
+}
+static ogs_inline void *ogs_asn_realloc(
+ void *oldptr, size_t size, const char *file_line)
+{
+ void *ptr = ogs_realloc(oldptr, size);
+ if (!ptr) {
+ ogs_fatal("asn_realloc() failed in `%s`", file_line);
+ ogs_assert_if_reached();
+ }
+
+ return ptr;
+}
+
+#define CALLOC(nmemb, size) ogs_asn_calloc(nmemb, size, OGS_FILE_LINE)
+#define MALLOC(size) ogs_asn_malloc(size, OGS_FILE_LINE)
+#define REALLOC(oldptr, size) ogs_asn_realloc(oldptr, size, OGS_FILE_LINE)
+#define FREEMEM(ptr) ogs_free(ptr)
+
+#endif
#define asn_debug_indent 0

View File

@@ -241,6 +241,7 @@ libcore_sources = files('''
ogs-process.h
ogs-sockaddr.h
ogs-socket.h
ogs-sockopt.h
ogs-sockpair.h
ogs-socknode.h
ogs-udp.h
@@ -275,6 +276,7 @@ libcore_sources = files('''
ogs-process.c
ogs-sockaddr.c
ogs-socket.c
ogs-sockopt.c
ogs-sockpair.c
ogs-socknode.c
ogs-udp.c

View File

@@ -198,7 +198,6 @@ char *ogs_supi_from_suci(char *suci)
{
#define MAX_SUCI_TOKEN 16
char *array[MAX_SUCI_TOKEN];
char *saveptr = NULL;
char *p, *tmp;
int i;
char *supi = NULL;
@@ -207,12 +206,10 @@ char *ogs_supi_from_suci(char *suci)
tmp = ogs_strdup(suci);
ogs_expect_or_return_val(tmp, NULL);
p = strtok_r(tmp, "-", &saveptr);
memset(array, 0, sizeof(array));
for (i = 0; i < MAX_SUCI_TOKEN && p; i++) {
array[i] = p;
p = strtok_r(NULL, "-", &saveptr);
p = tmp;
i = 0;
while((array[i++] = strsep(&p, "-"))) {
/* Empty Body */
}
SWITCH(array[0])
@@ -240,17 +237,17 @@ char *ogs_supi_from_suci(char *suci)
char *ogs_id_get_type(char *str)
{
char *saveptr = NULL;
char *p, *tmp;
char *token, *p, *tmp;
char *type = NULL;
ogs_assert(str);
tmp = ogs_strdup(str);
ogs_expect_or_return_val(tmp, NULL);
p = strtok_r(tmp, "-", &saveptr);
ogs_assert(p);
type = ogs_strdup(p);
p = tmp;
token = strsep(&p, "-");
ogs_assert(token);
type = ogs_strdup(token);
ogs_expect_or_return_val(type, NULL);
ogs_free(tmp);
@@ -259,19 +256,19 @@ char *ogs_id_get_type(char *str)
char *ogs_id_get_value(char *str)
{
char *saveptr = NULL;
char *p, *tmp;
char *token, *p, *tmp;
char *ueid = NULL;
ogs_assert(str);
tmp = ogs_strdup(str);
ogs_expect_or_return_val(tmp, NULL);
p = strtok_r(tmp, "-", &saveptr);
ogs_assert(p);
p = strtok_r(NULL, "-", &saveptr);
ogs_assert(p);
ueid = ogs_strdup(p);
p = tmp;
token = strsep(&p, "-");
ogs_assert(token);
token = strsep(&p, "-");
ogs_assert(token);
ueid = ogs_strdup(token);
ogs_expect_or_return_val(ueid, NULL);
ogs_free(tmp);
@@ -465,11 +462,11 @@ int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list)
return OGS_OK;
}
void ogs_sockaddr_to_ip(
int ogs_sockaddr_to_ip(
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, ogs_ip_t *ip)
{
ogs_assert(ip);
ogs_assert(addr || addr6);
ogs_expect_or_return_val(ip, OGS_ERROR);
ogs_expect_or_return_val(addr || addr6, OGS_ERROR);
memset(ip, 0, sizeof(ogs_ip_t));
@@ -489,6 +486,8 @@ void ogs_sockaddr_to_ip(
memcpy(ip->addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
} else
ogs_assert_if_reached();
return OGS_OK;
}
char *ogs_ipv4_to_string(uint32_t addr)

View File

@@ -30,6 +30,7 @@ extern "C" {
#define OGS_MAX_NUM_OF_SESS 4 /* Num of APN(Session) per UE */
#define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */
#define OGS_BEARER_PER_UE 8 /* Num of Bearer per UE */
#define OGS_MAX_NUM_OF_PACKET_BUFFER 64 /* Num of PacketBuffer per UE */
/*
@@ -121,7 +122,7 @@ uint16_t ogs_plmn_id_mcc(ogs_plmn_id_t *plmn_id);
uint16_t ogs_plmn_id_mnc(ogs_plmn_id_t *plmn_id);
uint16_t ogs_plmn_id_mnc_len(ogs_plmn_id_t *plmn_id);
void *ogs_plmn_id_build(ogs_plmn_id_t *plmn_id,
void *ogs_plmn_id_build(ogs_plmn_id_t *plmn_id,
uint16_t mcc, uint16_t mnc, uint16_t mnc_len);
char *ogs_serving_network_name_from_plmn_id(ogs_plmn_id_t *plmn_id);
@@ -238,7 +239,7 @@ ED3(uint8_t ipv4:1;,
} ogs_ip_t;
int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list);
void ogs_sockaddr_to_ip(
int ogs_sockaddr_to_ip(
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, ogs_ip_t *ip);
char *ogs_ipv4_to_string(uint32_t addr);
@@ -250,7 +251,34 @@ int ogs_ipv6prefix_from_string(
uint8_t *addr6, uint8_t *prefixlen, char *string);
/**************************************************
* 8.14 PDN Address Allocation (PAA) */
* GTPv1-C: TS 29.060 7.7.27 End User Address (EUA) */
#define OGS_PDP_EUA_ORG_ETSI 0
#define OGS_PDP_EUA_ORG_IETF 1
#define OGS_PDP_EUA_ETSI_PPP 1
#define OGS_PDP_EUA_IETF_IPV4 0x21
#define OGS_PDP_EUA_IETF_IPV6 0x57
#define OGS_PDP_EUA_IETF_IPV4V6 0x8D
typedef struct ogs_eua_s {
ED2(uint8_t spare:4;,
uint8_t organization:4;)
uint8_t type;
union {
/* PDU_SESSION_TYPE_IPV4 */
uint32_t addr;
/* PDU_SESSION_TYPE_IPV6 */
uint8_t addr6[OGS_IPV6_LEN];
/* PDU_SESSION_TYPE_IPV4V6 */
struct {
uint32_t addr;
uint8_t addr6[OGS_IPV6_LEN];
} __attribute__ ((packed)) both;
};
} __attribute__ ((packed)) ogs_eua_t;
/**************************************************
* GTPv2-C: TS 29.274 8.14 PDN Address Allocation (PAA) */
#define OGS_PAA_IPV4_LEN 5
#define OGS_PAA_IPV6_LEN 18
#define OGS_PAA_IPV4V6_LEN 22
@@ -265,7 +293,7 @@ ED2(uint8_t spare:5;,
uint8_t session_type:3;)
union {
/* PDU_SESSION_TYPE_IPV4 */
uint32_t addr;
uint32_t addr;
/* PDU_SESSION_TYPE_IPV6 */
struct {
@@ -283,7 +311,7 @@ ED2(uint8_t spare:5;,
/* IPv6 Prefix and Interface Identifier */
uint8_t addr6[OGS_IPV6_LEN];
};
uint32_t addr;
uint32_t addr;
} __attribute__ ((packed)) both;
};
} __attribute__ ((packed)) ogs_paa_t;
@@ -305,8 +333,8 @@ typedef struct ogs_qos_s {
struct {
/* Values 1 to 8 should only be assigned for services that are
* authorized to receive prioritized treatment within an operator domain.
* Values 9 to 15 may be assigned to resources that are authorized
* authorized to receive prioritized treatment within an operator domain.
* Values 9 to 15 may be assigned to resources that are authorized
* by the home network and thus applicable when a UE is roaming. */
uint8_t priority_level;
/*
@@ -370,7 +398,7 @@ typedef struct ogs_pcc_rule_s {
int flow_status;
uint32_t precedence;
ogs_qos_t qos;
} ogs_pcc_rule_t;
@@ -453,13 +481,14 @@ int ogs_fqdn_parse(char *dst, char *src, int len);
/**************************************************
* Protocol Configuration Options Structure
* 8.13 Protocol Configuration Options (PCO)
* 10.5.6.3 Protocol configuration options in 3GPP TS 24.008
* 8.13 Protocol Configuration Options (PCO)
* 10.5.6.3 Protocol configuration options in 3GPP TS 24.008
* RFC 3232 [103]
* RFC 1661 [102] */
#define OGS_PCO_PPP_FOR_USE_WITH_IP_PDP_TYPE_OR_IP_PDN_TYPE 0
#define OGS_PCO_ID_INTERNET_PROTOCOL_CONTROL_PROTOCOL 0x8021
#define OGS_PCO_ID_PASSWORD_AUTHENTICATION_PROTOCOL 0xc023
#define OGS_PCO_ID_CHALLENGE_HANDSHAKE_AUTHENTICATION_PROTOCOL 0xc223
#define OGS_PCO_ID_P_CSCF_IPV6_ADDRESS_REQUEST 0x0001
#define OGS_PCO_ID_DNS_SERVER_IPV6_ADDRESS_REQUEST 0x0003
@@ -470,20 +499,41 @@ int ogs_fqdn_parse(char *dst, char *src, int len);
#define OGS_PCO_ID_IPV4_LINK_MTU_REQUEST 0x0010
#define OGS_PCO_ID_MS_SUPPORT_LOCAL_ADDR_TFT_INDICATOR 0x0011
#define OGS_PCO_ID_P_CSCF_RE_SELECTION_SUPPORT 0x0012
enum ogs_pco_ipcp_options {
OGS_IPCP_OPT_IPADDR = 3,
OGS_IPCP_OPT_PRIMARY_DNS = 129,
OGS_IPCP_OPT_SECONDARY_DNS = 131,
};
typedef struct ogs_pco_ipcp_options_s {
uint8_t type;
uint8_t len;
uint32_t addr;
} __attribute__ ((packed)) ogs_pco_ipcp_options_t;
#define OGS_PCO_MAX_NUM_OF_IPCO_OPTIONS 4
#define OGS_PCO_MAX_NUM_OF_IPCP_OPTIONS 4
typedef struct ogs_pco_ipcp_s {
uint8_t code;
uint8_t identifier;
uint16_t len;
ogs_pco_ipcp_options_t options[OGS_PCO_MAX_NUM_OF_IPCO_OPTIONS];
ogs_pco_ipcp_options_t options[OGS_PCO_MAX_NUM_OF_IPCP_OPTIONS];
} __attribute__ ((packed)) ogs_pco_ipcp_t;
typedef struct ogs_pco_pap_s {
uint8_t code;
uint8_t identifier;
uint16_t len;
uint8_t welcome_len;
char welcome[255];
} __attribute__ ((packed)) ogs_pco_pap_t;
typedef struct ogs_pco_chap_s {
uint8_t code;
uint8_t identifier;
uint16_t len;
} __attribute__ ((packed)) ogs_pco_chap_t;
typedef struct ogs_pco_id_s {
uint16_t id;
uint8_t len;

View File

@@ -47,6 +47,7 @@
#include "core/ogs-signal.h"
#include "core/ogs-sockaddr.h"
#include "core/ogs-socket.h"
#include "core/ogs-sockopt.h"
#include "core/ogs-sockpair.h"
#include "core/ogs-socknode.h"
#include "core/ogs-udp.h"

View File

@@ -125,6 +125,8 @@ static int epoll_add(ogs_poll_t *poll)
if (poll->when & OGS_POLLOUT)
map->write = poll;
memset(&ee, 0, sizeof ee);
ee.events = 0;
if (map->read)
ee.events |= (EPOLLIN|EPOLLRDHUP);
@@ -164,6 +166,8 @@ static int epoll_remove(ogs_poll_t *poll)
if (poll->when & OGS_POLLOUT)
map->write = NULL;
memset(&ee, 0, sizeof ee);
ee.events = 0;
if (map->read)
ee.events |= (EPOLLIN|EPOLLRDHUP);

View File

@@ -32,6 +32,7 @@ extern "C" {
typedef DWORD ogs_err_t;
#define OGS_EPERM ERROR_ACCESS_DENIED
#define OGS_ENOMEM ERROR_NOT_ENOUGH_MEMORY
#define OGS_EACCES ERROR_ACCESS_DENIED
#define OGS_EEXIST ERROR_ALREADY_EXISTS
@@ -51,6 +52,7 @@ typedef DWORD ogs_err_t;
typedef int ogs_err_t;
#define OGS_EPERM EPERM
#define OGS_ENOMEM ENOMEM
#define OGS_EACCES EACCES
#define OGS_EEXIST EEXIST

View File

@@ -32,7 +32,7 @@ struct ogs_list_s {
struct ogs_list_s *prev, *next;
};
typedef struct ogs_list_s ogs_list_t;
typedef struct ogs_list_s ogs_lnode_t;;
typedef struct ogs_list_s ogs_lnode_t;
#define OGS_LIST(name) \
ogs_list_t name = { NULL, NULL }
@@ -42,6 +42,11 @@ typedef struct ogs_list_s ogs_lnode_t;;
(list)->next = (NULL); \
} while (0)
#define ogs_list_copy(dst, src) do { \
(dst)->prev = (src)->prev; \
(dst)->next = (src)->next; \
} while (0)
static ogs_inline void *ogs_list_first(const ogs_list_t *list)
{
return list->next;
@@ -64,15 +69,20 @@ static ogs_inline void *ogs_list_prev(void *lnode)
return node->prev;
}
#define ogs_list_entry(ptr, type, member) ogs_container_of(ptr, type, member)
#define ogs_list_entry(ptr, type, member) \
ptr ? ogs_container_of(ptr, type, member) : NULL
#define ogs_list_for_each(list, node) \
for (node = ogs_list_first(list); (node); \
node = ogs_list_next(node))
#define ogs_list_reverse_for_each(list, node) \
for (node = ogs_list_last(list); (node); \
node = ogs_list_prev(node))
#define ogs_list_for_each_entry(list, node, member) \
for (node = ogs_list_entry(ogs_list_first(list), typeof(*node), member); \
(&node->member); \
(node) && (&node->member); \
node = ogs_list_entry( \
ogs_list_next(&node->member), typeof(*node), member))
@@ -83,7 +93,7 @@ static ogs_inline void *ogs_list_prev(void *lnode)
#define ogs_list_for_each_entry_safe(list, n, node, member) \
for (node = ogs_list_entry(ogs_list_first(list), typeof(*node), member); \
(&node->member) && \
(node) && (&node->member) && \
(n = ogs_list_entry( \
ogs_list_next(&node->member), typeof(*node), member), 1); \
node = n)
@@ -118,7 +128,7 @@ static ogs_inline void ogs_list_remove(ogs_list_t *list, void *lnode)
{
ogs_list_t *node = lnode;
ogs_list_t *prev = node->prev;
ogs_list_t *next = node->next;;
ogs_list_t *next = node->next;
if (prev)
prev->next = next;

View File

@@ -22,6 +22,7 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_mem_domain
#if OGS_USE_TALLOC == 0
#define OGS_CLUSTER_128_SIZE 128
#define OGS_CLUSTER_256_SIZE 256
#define OGS_CLUSTER_512_SIZE 512
@@ -67,6 +68,7 @@ static ogs_pkbuf_pool_t *default_pool = NULL;
static ogs_cluster_t *cluster_alloc(
ogs_pkbuf_pool_t *pool, unsigned int size);
static void cluster_free(ogs_pkbuf_pool_t *pool, ogs_cluster_t *cluster);
#endif
void *ogs_pkbuf_put_data(
ogs_pkbuf_t *pkbuf, const void *data, unsigned int len)
@@ -79,16 +81,21 @@ void *ogs_pkbuf_put_data(
void ogs_pkbuf_init(void)
{
#if OGS_USE_TALLOC == 0
ogs_pool_init(&pkbuf_pool, ogs_core()->pkbuf.pool);
#endif
}
void ogs_pkbuf_final(void)
{
#if OGS_USE_TALLOC == 0
ogs_pool_final(&pkbuf_pool);
#endif
}
void ogs_pkbuf_default_init(ogs_pkbuf_config_t *config)
{
#if OGS_USE_TALLOC == 0
ogs_assert(config);
memset(config, 0, sizeof *config);
@@ -99,21 +106,27 @@ void ogs_pkbuf_default_init(ogs_pkbuf_config_t *config)
config->cluster_2048_pool = 1024;
config->cluster_8192_pool = 512;
config->cluster_big_pool = 8;
#endif
}
void ogs_pkbuf_default_create(ogs_pkbuf_config_t *config)
{
#if OGS_USE_TALLOC == 0
default_pool = ogs_pkbuf_pool_create(config);
#endif
}
void ogs_pkbuf_default_destroy(void)
{
#if OGS_USE_TALLOC == 0
ogs_pkbuf_pool_destroy(default_pool);
#endif
}
ogs_pkbuf_pool_t *ogs_pkbuf_pool_create(ogs_pkbuf_config_t *config)
{
ogs_pkbuf_pool_t *pool = NULL;
#if OGS_USE_TALLOC == 0
int tmp = 0;
ogs_assert(config);
@@ -139,6 +152,7 @@ ogs_pkbuf_pool_t *ogs_pkbuf_pool_create(ogs_pkbuf_config_t *config)
ogs_pool_init(&pool->cluster_2048, config->cluster_2048_pool);
ogs_pool_init(&pool->cluster_8192, config->cluster_8192_pool);
ogs_pool_init(&pool->cluster_big, config->cluster_big_pool);
#endif
return pool;
}
@@ -163,6 +177,7 @@ ogs_pkbuf_pool_t *ogs_pkbuf_pool_create(ogs_pkbuf_config_t *config)
void ogs_pkbuf_pool_destroy(ogs_pkbuf_pool_t *pool)
{
#if OGS_USE_TALLOC == 0
ogs_assert(pool);
ogs_pkbuf_pool_final(&pool->pkbuf);
@@ -179,11 +194,33 @@ void ogs_pkbuf_pool_destroy(ogs_pkbuf_pool_t *pool)
ogs_thread_mutex_destroy(&pool->mutex);
ogs_pool_free(&pkbuf_pool, pool);
#endif
}
ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
ogs_pkbuf_pool_t *pool, unsigned int size, const char *file_line)
{
#if OGS_USE_TALLOC
ogs_pkbuf_t *pkbuf = NULL;
pkbuf = ogs_talloc_zero_size(pool, sizeof(*pkbuf) + size, file_line);
if (!pkbuf) {
ogs_error("ogs_pkbuf_alloc() failed [size=%d]", size);
return NULL;
}
pkbuf->head = pkbuf->_data;
pkbuf->end = pkbuf->_data + size;
pkbuf->len = 0;
pkbuf->data = pkbuf->_data;
pkbuf->tail = pkbuf->_data;
pkbuf->file_line = file_line; /* For debug */
return pkbuf;
#else
ogs_pkbuf_t *pkbuf = NULL;
ogs_cluster_t *cluster = NULL;
@@ -210,8 +247,6 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
cluster->ref++;
ogs_thread_mutex_unlock(&pool->mutex);
pkbuf->cluster = cluster;
pkbuf->len = 0;
@@ -225,11 +260,17 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
pkbuf->pool = pool;
ogs_thread_mutex_unlock(&pool->mutex);
return pkbuf;
#endif
}
void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
{
#if OGS_USE_TALLOC
ogs_talloc_free(pkbuf, OGS_FILE_LINE);
#else
ogs_pkbuf_pool_t *pool = NULL;
ogs_cluster_t *cluster = NULL;
ogs_assert(pkbuf);
@@ -237,11 +278,11 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
pool = pkbuf->pool;
ogs_assert(pool);
ogs_thread_mutex_lock(&pool->mutex);
cluster = pkbuf->cluster;
ogs_assert(cluster);
ogs_thread_mutex_lock(&pool->mutex);
cluster->ref--;
if (cluster->ref == 0)
cluster_free(pool, pkbuf->cluster);
@@ -249,10 +290,33 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
ogs_pool_free(&pool->pkbuf, pkbuf);
ogs_thread_mutex_unlock(&pool->mutex);
#endif
}
ogs_pkbuf_t *ogs_pkbuf_copy_debug(ogs_pkbuf_t *pkbuf, const char *file_line)
{
#if OGS_USE_TALLOC
ogs_pkbuf_t *newbuf;
int size = pkbuf->end - pkbuf->head;
ogs_assert(size > 0);
newbuf = ogs_pkbuf_alloc_debug(NULL, size, file_line);
if (!pkbuf) {
ogs_error("ogs_pkbuf_alloc() failed [size=%d]", size);
return NULL;
}
/* copy data */
memcpy(newbuf->_data, pkbuf->_data, size);
/* copy header */
newbuf->len = pkbuf->len;
newbuf->tail += pkbuf->tail - pkbuf->_data;
newbuf->data += pkbuf->data - pkbuf->_data;
return newbuf;
#else
ogs_pkbuf_pool_t *pool = NULL;
ogs_pkbuf_t *newbuf = NULL;
@@ -274,10 +338,12 @@ ogs_pkbuf_t *ogs_pkbuf_copy_debug(ogs_pkbuf_t *pkbuf, const char *file_line)
newbuf->cluster->ref++;
ogs_thread_mutex_unlock(&pool->mutex);
#endif
return newbuf;
}
#if OGS_USE_TALLOC == 0
static ogs_cluster_t *cluster_alloc(
ogs_pkbuf_pool_t *pool, unsigned int size)
{
@@ -363,3 +429,4 @@ static void cluster_free(ogs_pkbuf_pool_t *pool, ogs_cluster_t *cluster)
ogs_pool_free(&pool->cluster, cluster);
}
#endif

View File

@@ -35,7 +35,11 @@ typedef struct ogs_cluster_s {
unsigned int ref;
} ogs_cluster_t;
#if OGS_USE_TALLOC
typedef void ogs_pkbuf_pool_t;
#else
typedef struct ogs_pkbuf_pool_s ogs_pkbuf_pool_t;
#endif
typedef struct ogs_pkbuf_s {
ogs_lnode_t lnode;
@@ -54,6 +58,8 @@ typedef struct ogs_pkbuf_s {
const char *file_line;
ogs_pkbuf_pool_t *pool;
unsigned char _data[0]; /*!< optional immediate data array */
} ogs_pkbuf_t;
typedef struct ogs_pkbuf_config_s {
@@ -108,12 +114,12 @@ static ogs_inline void *ogs_pkbuf_put(ogs_pkbuf_t *pkbuf, unsigned int len)
{
void *tmp = pkbuf->tail;
if (ogs_unlikely(ogs_pkbuf_tailroom(pkbuf) < (int)len))
ogs_assert_if_reached();
pkbuf->tail += len;
pkbuf->len += len;
if (ogs_unlikely(pkbuf->tail > pkbuf->end))
ogs_assert_if_reached();
return tmp;
}
@@ -138,12 +144,12 @@ static ogs_inline void ogs_pkbuf_put_u32(ogs_pkbuf_t *pkbuf, uint32_t val)
static ogs_inline void *ogs_pkbuf_push(ogs_pkbuf_t *pkbuf, unsigned int len)
{
if (ogs_unlikely(ogs_pkbuf_headroom(pkbuf) < (int)len))
ogs_assert_if_reached();
pkbuf->data -= len;
pkbuf->len += len;
if (ogs_unlikely(pkbuf->data < pkbuf->head))
ogs_assert_if_reached();
return pkbuf->data;
}
@@ -160,12 +166,19 @@ static ogs_inline void *ogs_pkbuf_pull(ogs_pkbuf_t *pkbuf, unsigned int len)
NULL : ogs_pkbuf_pull_inline(pkbuf, len);
}
static ogs_inline void ogs_pkbuf_trim(ogs_pkbuf_t *pkbuf, unsigned int len)
static ogs_inline int ogs_pkbuf_trim(ogs_pkbuf_t *pkbuf, int len)
{
if (pkbuf->len > len) {
pkbuf->tail = pkbuf->data + len;
pkbuf->len = len;
if (ogs_unlikely(len < 0))
ogs_assert_if_reached();
if (ogs_unlikely(len > pkbuf->len)) {
ogs_error("len(%d) > pkbuf->len(%d)", len, pkbuf->len);
return OGS_ERROR;
}
pkbuf->tail = pkbuf->data + len;
pkbuf->len = len;
return OGS_OK;
}
#ifdef __cplusplus

View File

@@ -70,7 +70,7 @@ int ogs_getnameinfo(
}
#endif
int ogs_getaddrinfo(ogs_sockaddr_t **sa_list,
int ogs_getaddrinfo(ogs_sockaddr_t **sa_list,
int family, const char *hostname, uint16_t port, int flags)
{
*sa_list = NULL;
@@ -93,7 +93,7 @@ int ogs_freeaddrinfo(ogs_sockaddr_t *sa_list)
return OGS_OK;
}
int ogs_addaddrinfo(ogs_sockaddr_t **sa_list,
int ogs_addaddrinfo(ogs_sockaddr_t **sa_list,
int family, const char *hostname, uint16_t port, int flags)
{
int rc;
@@ -246,7 +246,7 @@ int ogs_sortaddrinfo(ogs_sockaddr_t **sa_list, int family)
new->next = addr;
}
}
*sa_list = head;
return OGS_OK;
@@ -312,11 +312,11 @@ ogs_sockaddr_t *ogs_link_local_addr_by_sa(const ogs_sockaddr_t *sa)
return ogs_link_local_addr(NULL, sa);
}
int ogs_filter_ip_version(ogs_sockaddr_t **addr,
int ogs_filter_ip_version(ogs_sockaddr_t **addr,
int no_ipv4, int no_ipv6, int prefer_ipv4)
{
int rv;
if (no_ipv4 == 1) {
rv = ogs_filteraddrinfo(addr, AF_INET6);
ogs_assert(rv == OGS_OK);
@@ -491,7 +491,7 @@ static int parse_ip(
/* supported flavors of IP:
*
* . IPv6 numeric address string (e.g., "fe80::1")
*
*
* IMPORTANT: Don't store IPv4-mapped IPv6 address as an IPv6 address.
*
* . IPv4 numeric address string (e.g., "127.0.0.1")
@@ -506,7 +506,7 @@ static int parse_ip(
if (rc == 1) {
if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ipsub->sub)) {
/* ipsubnet_test() assumes that we don't create IPv4-mapped IPv6
* addresses; this of course forces the user to specify
* addresses; this of course forces the user to specify
* IPv4 addresses in a.b.c.d style instead of ::ffff:a.b.c.d style.
*/
ogs_error("Cannot support IPv4-mapped IPv6: "
@@ -535,7 +535,7 @@ static int looks_like_ip(const char *ipstr)
{
if (strlen(ipstr) == 0)
return 0;
if (strchr(ipstr, ':')) {
/* definitely not a hostname;
* assume it is intended to be an IPv6 address */
@@ -572,13 +572,13 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
ogs_assert(ipstr);
/* filter out stuff which doesn't look remotely like an IP address;
* this helps callers like mod_access which have a syntax allowing
* this helps callers like mod_access which have a syntax allowing
* hostname or IP address;
* CORE_EINVAL tells the caller that it was probably not intended
* CORE_EINVAL tells the caller that it was probably not intended
* to be an IP address
*/
if (!looks_like_ip(ipstr)) {
ogs_error("looks_like_ip() is failed");
ogs_error("looks_like_ip(%s, %s) failed", ipstr, mask_or_numbits);
return OGS_ERROR;
}
@@ -587,7 +587,7 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
rv = parse_ip(ipsub, ipstr, mask_or_numbits == NULL);
if (rv != OGS_OK) {
ogs_error("parse_ip() is failed");
ogs_error("parse_ip(%s, %s) failed", ipstr, mask_or_numbits);
return rv;
}
@@ -619,7 +619,7 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
ipsub->family == AF_INET) {
/* valid IPv4 netmask */
} else {
ogs_error("Bad netmask");
ogs_error("Bad netmask %s", mask_or_numbits);
return OGS_ERROR;
}
}

View File

@@ -53,12 +53,12 @@ void ogs_socket_final(void)
ogs_sock_t *ogs_sock_create(void)
{
ogs_sock_t *sock = NULL;
sock = ogs_calloc(1, sizeof(*sock));
ogs_expect_or_return_val(sock, NULL);
sock->fd = INVALID_SOCKET;
return sock;
}
@@ -131,7 +131,7 @@ int ogs_sock_connect(ogs_sock_t *sock, ogs_sockaddr_t *addr)
ogs_assert(addrlen);
if (connect(sock->fd, &addr->sa, addrlen) != 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"socket connect[%s]:%d failed",
OGS_ADDR(addr, buf), OGS_PORT(addr));
return OGS_ERROR;
@@ -255,79 +255,3 @@ int ogs_closesocket(ogs_socket_t fd)
return OGS_OK;
}
int ogs_nonblocking(ogs_socket_t fd)
{
#ifdef _WIN32
int rc;
ogs_assert(fd != INVALID_SOCKET);
u_long io_mode = 1;
rc = ioctlsocket(fd, FIONBIO, &io_mode);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ioctlsocket failed");
return OGS_ERROR;
}
#else
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFL, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFL failed");
return OGS_ERROR;
}
if (!(flags & O_NONBLOCK)) {
rc = fcntl(fd, F_SETFL, (flags | O_NONBLOCK));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFL failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_closeonexec(ogs_socket_t fd)
{
#ifndef _WIN32
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFD, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFD failed");
return OGS_ERROR;
}
if (!(flags & FD_CLOEXEC)) {
rc = fcntl(fd, F_SETFD, (flags | FD_CLOEXEC));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFD failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_listen_reusable(ogs_socket_t fd)
{
#if defined(SO_REUSEADDR) && !defined(_WIN32)
int rc;
int on = 1;
ogs_assert(fd != INVALID_SOCKET);
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_REUSEADDR) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}

View File

@@ -71,10 +71,6 @@ ssize_t ogs_recvfrom(ogs_socket_t fd,
int ogs_closesocket(ogs_socket_t fd);
int ogs_nonblocking(ogs_socket_t fd);
int ogs_closeonexec(ogs_socket_t fd);
int ogs_listen_reusable(ogs_socket_t fd);
#ifdef __cplusplus
}
#endif

View File

@@ -51,6 +51,8 @@ void ogs_socknode_free(ogs_socknode_t *node)
ogs_assert(node);
ogs_freeaddrinfo(node->addr);
if (node->dev)
ogs_free(node->dev);
if (node->poll)
ogs_pollset_remove(node->poll);
if (node->sock) {
@@ -59,11 +61,13 @@ void ogs_socknode_free(ogs_socknode_t *node)
else
ogs_sock_destroy(node->sock);
}
if (node->option)
ogs_free(node->option);
ogs_free(node);
}
ogs_socknode_t *ogs_socknode_add(
ogs_list_t *list, int family, ogs_sockaddr_t *addr)
ogs_socknode_t *ogs_socknode_add(ogs_list_t *list,
int family, ogs_sockaddr_t *addr, ogs_sockopt_t *option)
{
ogs_socknode_t *node = NULL;
ogs_sockaddr_t *dup = NULL;
@@ -79,6 +83,9 @@ ogs_socknode_t *ogs_socknode_add(
node = ogs_socknode_new(dup);
ogs_assert(node);
ogs_list_add(list, node);
if (option)
node->option = ogs_memdup(option, sizeof *option);
}
return node;
@@ -100,8 +107,8 @@ void ogs_socknode_remove_all(ogs_list_t *list)
ogs_socknode_remove(list, node);
}
int ogs_socknode_probe(
ogs_list_t *list, ogs_list_t *list6, const char *dev, uint16_t port)
int ogs_socknode_probe(ogs_list_t *list, ogs_list_t *list6,
const char *dev, uint16_t port, ogs_sockopt_t *option)
{
#if defined(HAVE_GETIFADDRS)
ogs_socknode_t *node = NULL;
@@ -164,6 +171,8 @@ int ogs_socknode_probe(
node = ogs_calloc(1, sizeof(ogs_socknode_t));
node->addr = addr;
if (dev)
node->dev = ogs_strdup(dev);
if (addr->ogs_sa_family == AF_INET) {
ogs_assert(list);
@@ -173,6 +182,9 @@ int ogs_socknode_probe(
ogs_list_add(list6, node);
} else
ogs_assert_if_reached();
if (option)
node->option = ogs_memdup(option, sizeof *option);
}
freeifaddrs(iflist);
@@ -186,6 +198,7 @@ int ogs_socknode_probe(
}
#if 0 /* deprecated */
int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list)
{
#if defined(HAVE_GETIFADDRS)
@@ -243,6 +256,7 @@ int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list)
return OGS_ERROR;
#endif
}
#endif
void ogs_socknode_set_cleanup(
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *))

View File

@@ -35,23 +35,28 @@ typedef struct ogs_socknode_s {
ogs_lnode_t node;
ogs_sockaddr_t *addr;
char *dev;
ogs_sock_t *sock;
void (*cleanup)(ogs_sock_t *sock);
ogs_poll_t *poll;
ogs_sockopt_t *option;
} ogs_socknode_t;
ogs_socknode_t *ogs_socknode_new(ogs_sockaddr_t *addr);
void ogs_socknode_free(ogs_socknode_t *node);
ogs_socknode_t *ogs_socknode_add(
ogs_list_t *list, int family, ogs_sockaddr_t *sa_list);
ogs_socknode_t *ogs_socknode_add(ogs_list_t *list,
int family, ogs_sockaddr_t *addr, ogs_sockopt_t *option);
void ogs_socknode_remove(ogs_list_t *list, ogs_socknode_t *node);
void ogs_socknode_remove_all(ogs_list_t *list);
int ogs_socknode_probe(
ogs_list_t *list, ogs_list_t *list6, const char *dev, uint16_t port);
int ogs_socknode_probe(ogs_list_t *list, ogs_list_t *list6,
const char *dev, uint16_t port, ogs_sockopt_t *option);
#if 0 /* deprecated */
int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list);
#endif
void ogs_socknode_set_cleanup(
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *));

197
lib/core/ogs-sockopt.c Normal file
View File

@@ -0,0 +1,197 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "core-config-private.h"
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "ogs-core.h"
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
void ogs_sockopt_init(ogs_sockopt_t *option)
{
ogs_assert(option);
memset(option, 0, sizeof *option);
option->sctp.spp_hbinterval = 5000; /* 5 seconds */
option->sctp.spp_sackdelay = 200; /* 200 ms */
option->sctp.srto_initial = 3000; /* 3 seconds */
option->sctp.srto_min = 1000; /* 1 seconds */
option->sctp.srto_max = 5000; /* 5 seconds */
option->sctp.sinit_num_ostreams = OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
option->sctp.sinit_max_instreams = 65535;
option->sctp.sinit_max_attempts = 4;
option->sctp.sinit_max_init_timeo = 8000; /* 8 seconds */
option->sctp_nodelay = true;
option->tcp_nodelay = true;
}
int ogs_nonblocking(ogs_socket_t fd)
{
#ifdef _WIN32
int rc;
ogs_assert(fd != INVALID_SOCKET);
u_long io_mode = 1;
rc = ioctlsocket(fd, FIONBIO, &io_mode);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ioctlsocket failed");
return OGS_ERROR;
}
#else
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFL, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFL failed");
return OGS_ERROR;
}
if (!(flags & O_NONBLOCK)) {
rc = fcntl(fd, F_SETFL, (flags | O_NONBLOCK));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFL failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_closeonexec(ogs_socket_t fd)
{
#ifndef _WIN32
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFD, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFD failed");
return OGS_ERROR;
}
if (!(flags & FD_CLOEXEC)) {
rc = fcntl(fd, F_SETFD, (flags | FD_CLOEXEC));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFD failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_listen_reusable(ogs_socket_t fd, int on)
{
#if defined(SO_REUSEADDR) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_debug("Turn on SO_REUSEADDR");
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_REUSEADDR) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_tcp_nodelay(ogs_socket_t fd, int on)
{
#if defined(TCP_NODELAY) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_debug("Turn on TCP_NODELAY");
rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(IPPROTO_TCP, TCP_NODELAY) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_so_linger(ogs_socket_t fd, int l_linger)
{
#if defined(SO_LINGER) && !defined(_WIN32)
struct linger l;
int rc;
ogs_assert(fd != INVALID_SOCKET);
memset(&l, 0, sizeof(l));
l.l_onoff = 1;
l.l_linger = l_linger;
ogs_debug("SO_LINGER:[%d]", l_linger);
rc = setsockopt(fd, SOL_SOCKET, SO_LINGER,
(void *)&l, sizeof(struct linger));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_LINGER) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_bind_to_device(ogs_socket_t fd, const char *device)
{
#if defined(SO_BINDTODEVICE) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(device);
ogs_debug("SO_BINDTODEVICE:[%s]", device);
rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
if (rc != OGS_OK) {
int err = ogs_errno;
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_BINDTODEVICE, %s) failed", device);
if (err == OGS_EPERM)
ogs_error("You need to grant CAP_NET_RAW privileges to use SO_BINDTODEVICE.");
return OGS_ERROR;
}
#endif
return OGS_OK;
}

68
lib/core/ogs-sockopt.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_CORE_INSIDE) && !defined(OGS_CORE_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_SOCKOPT_H
#define OGS_SOCKOPT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ogs_sockopt_s {
struct {
uint32_t spp_hbinterval;
uint32_t spp_sackdelay;
uint32_t srto_initial;
uint32_t srto_min;
uint32_t srto_max;
uint16_t sinit_num_ostreams;
uint16_t sinit_max_instreams;
uint16_t sinit_max_attempts;
uint16_t sinit_max_init_timeo;
} sctp;
bool sctp_nodelay;
bool tcp_nodelay;
struct {
bool l_onoff;
int l_linger;
} so_linger;
const char *so_bindtodevice;
} ogs_sockopt_t;
void ogs_sockopt_init(ogs_sockopt_t *option);
int ogs_nonblocking(ogs_socket_t fd);
int ogs_closeonexec(ogs_socket_t fd);
int ogs_listen_reusable(ogs_socket_t fd, int on);
int ogs_tcp_nodelay(ogs_socket_t fd, int on);
int ogs_so_linger(ogs_socket_t fd, int l_linger);
int ogs_bind_to_device(ogs_socket_t fd, const char *device);
#ifdef __cplusplus
}
#endif
#endif /* OGS_SOCKOPT_H */

View File

@@ -22,21 +22,38 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
ogs_sock_t *ogs_tcp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
int rv;
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while(addr) {
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (new) {
rv = ogs_listen_reusable(new->fd);
if (option.tcp_nodelay == true) {
rv = ogs_tcp_nodelay(new->fd, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("TCP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_so_linger(new->fd, 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) {
@@ -54,31 +71,47 @@ ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"tcp_server() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
rv = ogs_sock_listen(new);
ogs_assert(rv == OGS_OK);
node->sock = new;
return new;
}
ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
ogs_sock_t *ogs_tcp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (new) {
if (option.sctp_nodelay == true) {
rv = ogs_tcp_nodelay(new->fd, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("TCP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_so_linger(new->fd, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
if (ogs_sock_connect(new, addr) == OGS_OK) {
ogs_debug("tcp_client() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
@@ -94,11 +127,9 @@ ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"tcp_client() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = new;
return new;
}

View File

@@ -28,8 +28,10 @@
extern "C" {
#endif
ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node);
ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node);
ogs_sock_t *ogs_tcp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_tcp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
#ifdef __cplusplus
}

View File

@@ -167,6 +167,40 @@ int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec)
return status;
}
/* RFC 5905 A.1.1, A.4
* PFCP entity uses NTP timestamp(1900), but Open5GS uses UNIX(1970).
*
* One is the offset between the two epochs.
* Unix uses an epoch located at 1/1/1970-00:00h (UTC) and
* NTP uses 1/1/1900-00:00h. This leads to an offset equivalent
* to 70 years in seconds (there are 17 leap years
* between the two dates so the offset is
*
* (70*365 + 17)*86400 = 2208988800
*
* to be substracted from NTP time to get Unix struct timeval.
*/
uint32_t ogs_time_ntp32_now(void)
{
int rc;
struct timeval tv;
rc = ogs_gettimeofday(&tv);
ogs_assert(rc == 0);
return ogs_time_to_ntp32(tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec);
}
ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp)
{
if (ntp_timestamp < OGS_1970_1900_SEC_DIFF)
return 0;
return (ntp_timestamp - OGS_1970_1900_SEC_DIFF) * OGS_USEC_PER_SEC;
}
uint32_t ogs_time_to_ntp32(ogs_time_t time)
{
return (time / OGS_USEC_PER_SEC) + OGS_1970_1900_SEC_DIFF;
}
int ogs_timezone(void)
{
#if defined(_WIN32)

View File

@@ -99,6 +99,11 @@ ogs_time_t ogs_time_now(void); /* This returns GMT */
int ogs_time_from_lt(ogs_time_t *t, struct tm *tm, int tm_usec);
int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec);
#define OGS_1970_1900_SEC_DIFF 2208988800UL /* 1970 - 1900 in seconds */
uint32_t ogs_time_ntp32_now(void); /* This returns NTP timestamp (1900) */
ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp);
uint32_t ogs_time_to_ntp32(ogs_time_t time);
/** @return number of microseconds since an arbitrary point */
ogs_time_t ogs_get_monotonic_time(void);
/** @return the GMT offset in seconds */

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* This file is part of Open5GS.
*
@@ -36,38 +37,89 @@ ogs_tlv_desc_t ogs_tlv_desc_more7 = {
ogs_tlv_desc_t ogs_tlv_desc_more8 = {
OGS_TLV_MORE, "More", 0, 8, 0, 0, { NULL } };
static ogs_tlv_t *tlv_add_leaf(
ogs_tlv_t *parent_tlv, ogs_tlv_t *tlv, ogs_tlv_desc_t *desc, void *msg)
/* Return specific TLV mode based on its TLV description type and the msg
* provided mode (used to know the type length) */
static uint8_t tlv_ctype2mode(ogs_tlv_type_e ctype, uint8_t msg_mode)
{
switch(ctype) {
case OGS_TLV_UINT8:
case OGS_TLV_UINT16:
case OGS_TLV_UINT24:
case OGS_TLV_UINT32:
case OGS_TLV_INT8:
case OGS_TLV_INT16:
case OGS_TLV_INT24:
case OGS_TLV_INT32:
case OGS_TLV_FIXED_STR:
case OGS_TLV_VAR_STR:
case OGS_TLV_NULL:
case OGS_TLV_MORE:
case OGS_TLV_COMPOUND:
case OGS_TLV_MESSAGE:
return msg_mode;
case OGS_TV_UINT8:
case OGS_TV_UINT16:
case OGS_TV_UINT24:
case OGS_TV_UINT32:
case OGS_TV_INT8:
case OGS_TV_INT16:
case OGS_TV_INT24:
case OGS_TV_INT32:
case OGS_TV_FIXED_STR:
case OGS_TV_VAR_STR:
case OGS_TV_NULL:
case OGS_TV_MORE:
if (msg_mode == OGS_TLV_MODE_T2_L2)
return OGS_TLV_MODE_T1; /* Here return OGS_TLV_MODE_T2 if ever existing */
else
return OGS_TLV_MODE_T1;
default:
ogs_assert_if_reached();
break;
}
}
static ogs_tlv_t *tlv_add_leaf(
ogs_tlv_t *parent_tlv, ogs_tlv_t *tlv, ogs_tlv_desc_t *desc, void *msg, uint8_t msg_mode)
{
uint8_t tlv_mode = tlv_ctype2mode(desc->ctype, msg_mode);
switch (desc->ctype) {
case OGS_TLV_UINT8:
case OGS_TLV_INT8:
case OGS_TV_UINT8:
case OGS_TV_INT8:
{
ogs_tlv_uint8_t *v = (ogs_tlv_uint8_t *)msg;
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, 1, desc->instance, &v->u8);
else
tlv = ogs_tlv_add(tlv, desc->type, 1, desc->instance, &v->u8);
tlv = ogs_tlv_add(tlv, tlv_mode, desc->type, 1, desc->instance, &v->u8);
ogs_expect_or_return_val(tlv, NULL);
break;
}
case OGS_TLV_UINT16:
case OGS_TLV_INT16:
case OGS_TV_UINT16:
case OGS_TV_INT16:
{
ogs_tlv_uint16_t *v = (ogs_tlv_uint16_t *)msg;
v->u16 = htobe16(v->u16);
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, 2, desc->instance, &v->u16);
else
tlv = ogs_tlv_add(tlv, desc->type, 2, desc->instance, &v->u16);
tlv = ogs_tlv_add(tlv, tlv_mode, desc->type, 2, desc->instance, &v->u16);
ogs_expect_or_return_val(tlv, NULL);
break;
}
case OGS_TLV_UINT24:
case OGS_TLV_INT24:
case OGS_TV_UINT24:
case OGS_TV_INT24:
{
ogs_tlv_uint24_t *v = (ogs_tlv_uint24_t *)msg;
@@ -75,38 +127,41 @@ static ogs_tlv_t *tlv_add_leaf(
v->u24 = htobe32(v->u24);
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, 3, desc->instance, &v->u24);
else
tlv = ogs_tlv_add(tlv, desc->type, 3, desc->instance, &v->u24);
tlv = ogs_tlv_add(tlv, tlv_mode, desc->type, 3, desc->instance, &v->u24);
ogs_expect_or_return_val(tlv, NULL);
break;
}
case OGS_TLV_UINT32:
case OGS_TLV_INT32:
case OGS_TV_UINT32:
case OGS_TV_INT32:
{
ogs_tlv_uint32_t *v = (ogs_tlv_uint32_t *)msg;
v->u32 = htobe32(v->u32);
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, 4, desc->instance, &v->u32);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_mode,
desc->type, 4, desc->instance, &v->u32);
ogs_expect_or_return_val(tlv, NULL);
break;
}
case OGS_TLV_FIXED_STR:
case OGS_TV_FIXED_STR:
{
ogs_tlv_octet_t *v = (ogs_tlv_octet_t *)msg;
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, desc->length, desc->instance, v->data);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_mode,
desc->type, desc->length, desc->instance, v->data);
ogs_expect_or_return_val(tlv, NULL);
break;
@@ -122,21 +177,22 @@ static ogs_tlv_t *tlv_add_leaf(
}
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, v->len, desc->instance, v->data);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_mode,
desc->type, v->len, desc->instance, v->data);
ogs_expect_or_return_val(tlv, NULL);
break;
}
case OGS_TLV_NULL:
case OGS_TV_NULL:
{
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_mode,
desc->type, 0, desc->instance, NULL);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_mode,
desc->type, 0, desc->instance, NULL);
ogs_expect_or_return_val(tlv, NULL);
break;
@@ -150,7 +206,7 @@ static ogs_tlv_t *tlv_add_leaf(
}
static uint32_t tlv_add_compound(ogs_tlv_t **root, ogs_tlv_t *parent_tlv,
ogs_tlv_desc_t *parent_desc, void *msg, int depth)
ogs_tlv_desc_t *parent_desc, void *msg, int depth, uint8_t mode)
{
ogs_tlv_presence_t *presence_p;
ogs_tlv_desc_t *desc = NULL, *next_desc = NULL;
@@ -186,15 +242,15 @@ static uint32_t tlv_add_compound(ogs_tlv_t **root, ogs_tlv_t *parent_tlv,
desc->vsize, p + offset2);
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_ctype2mode(desc->ctype, mode),
desc->type, 0, desc->instance, NULL);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_ctype2mode(desc->ctype, mode),
desc->type, 0, desc->instance, NULL);
r = tlv_add_compound(&emb_tlv, tlv, desc,
p + offset2 + sizeof(ogs_tlv_presence_t),
depth + 1);
depth + 1, mode);
ogs_expect_or_return_val(r > 0 && emb_tlv, 0);
count += 1 + r;
} else {
@@ -204,7 +260,7 @@ static uint32_t tlv_add_compound(ogs_tlv_t **root, ogs_tlv_t *parent_tlv,
desc->instance, desc->ctype, desc->vsize,
p + offset2);
tlv = tlv_add_leaf(parent_tlv, tlv, desc, p + offset2);
tlv = tlv_add_leaf(parent_tlv, tlv, desc, p + offset2, mode);
ogs_expect_or_return_val(tlv, 0);
count++;
}
@@ -226,15 +282,15 @@ static uint32_t tlv_add_compound(ogs_tlv_t **root, ogs_tlv_t *parent_tlv,
desc->vsize, p + offset);
if (parent_tlv)
tlv = ogs_tlv_embed(parent_tlv,
tlv = ogs_tlv_embed(parent_tlv, tlv_ctype2mode(desc->ctype, mode),
desc->type, 0, desc->instance, NULL);
else
tlv = ogs_tlv_add(tlv,
tlv = ogs_tlv_add(tlv, tlv_ctype2mode(desc->ctype, mode),
desc->type, 0, desc->instance, NULL);
r = tlv_add_compound(&emb_tlv, tlv, desc,
p + offset + sizeof(ogs_tlv_presence_t),
depth + 1);
depth + 1, mode);
ogs_expect_or_return_val(r > 0 && emb_tlv, 0);
count += 1 + r;
} else {
@@ -244,7 +300,7 @@ static uint32_t tlv_add_compound(ogs_tlv_t **root, ogs_tlv_t *parent_tlv,
desc->instance, desc->ctype, desc->vsize,
p + offset);
tlv = tlv_add_leaf(parent_tlv, tlv, desc, p + offset);
tlv = tlv_add_leaf(parent_tlv, tlv, desc, p + offset, mode);
ogs_expect_or_return_val(tlv, 0);
count++;
}
@@ -271,10 +327,10 @@ ogs_pkbuf_t *ogs_tlv_build_msg(ogs_tlv_desc_t *desc, void *msg, int mode)
ogs_assert(desc->ctype == OGS_TLV_MESSAGE);
if (desc->child_descs[0]) {
r = tlv_add_compound(&root, NULL, desc, msg, 0);
r = tlv_add_compound(&root, NULL, desc, msg, 0, mode);
ogs_expect_or_return_val(r > 0 && root, NULL);
length = ogs_tlv_calc_length(root, mode);
length = ogs_tlv_calc_length(root);
} else {
length = 0;
}
@@ -284,7 +340,7 @@ ogs_pkbuf_t *ogs_tlv_build_msg(ogs_tlv_desc_t *desc, void *msg, int mode)
ogs_pkbuf_put(pkbuf, length);
if (desc->child_descs[0]) {
rendlen = ogs_tlv_render(root, pkbuf->data, length, mode);
rendlen = ogs_tlv_render(root, pkbuf->data, length);
ogs_expect_or_return_val(rendlen == length, NULL);
ogs_tlv_free_all(root);
@@ -293,21 +349,24 @@ ogs_pkbuf_t *ogs_tlv_build_msg(ogs_tlv_desc_t *desc, void *msg, int mode)
return pkbuf;
}
static ogs_tlv_desc_t* tlv_find_desc(uint8_t *desc_index,
uint32_t *tlv_offset, ogs_tlv_desc_t *parent_desc, ogs_tlv_t *tlv)
static ogs_tlv_desc_t* tlv_find_desc_by_type_inst(uint8_t *desc_index,
uint32_t *tlv_offset, ogs_tlv_desc_t *parent_desc, uint16_t match_type, uint8_t match_instance, uint8_t match_type_pos)
{
ogs_tlv_desc_t *prev_desc = NULL, *desc = NULL;
int i, offset = 0;
unsigned match_i = 0;
ogs_assert(parent_desc);
ogs_assert(tlv);
for (i = 0, desc = parent_desc->child_descs[i]; desc != NULL;
i++, desc = parent_desc->child_descs[i]) {
if (desc->type == tlv->type && desc->instance == tlv->instance) {
*desc_index = i;
*tlv_offset = offset;
break;
if (desc->type == match_type && desc->instance == match_instance) {
if (match_i == match_type_pos) {
*desc_index = i;
*tlv_offset = offset;
break;
}
match_i++;
}
if (desc->ctype == OGS_TLV_MORE) {
@@ -330,6 +389,8 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
ogs_assert(tlv);
switch (desc->ctype) {
case OGS_TV_UINT8:
case OGS_TV_INT8:
case OGS_TLV_UINT8:
case OGS_TLV_INT8:
{
@@ -343,6 +404,8 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
v->u8 = *(uint8_t*)(tlv->value);
break;
}
case OGS_TV_UINT16:
case OGS_TV_INT16:
case OGS_TLV_UINT16:
case OGS_TLV_INT16:
{
@@ -357,6 +420,8 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
((((uint8_t*)tlv->value)[1] )&0x00ff);
break;
}
case OGS_TV_UINT24:
case OGS_TV_INT24:
case OGS_TLV_UINT24:
case OGS_TLV_INT24:
{
@@ -372,6 +437,8 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
((((uint8_t*)tlv->value)[2] )&0x000000ff);
break;
}
case OGS_TV_UINT32:
case OGS_TV_INT32:
case OGS_TLV_UINT32:
case OGS_TLV_INT32:
{
@@ -388,6 +455,7 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
((((uint8_t*)tlv->value)[3] )&0x000000ff);
break;
}
case OGS_TV_FIXED_STR:
case OGS_TLV_FIXED_STR:
{
ogs_tlv_octet_t *v = (ogs_tlv_octet_t *)msg;
@@ -411,6 +479,7 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
v->len = tlv->length;
break;
}
case OGS_TV_NULL:
case OGS_TLV_NULL:
{
if (tlv->length != 0) {
@@ -427,6 +496,50 @@ static int tlv_parse_leaf(void *msg, ogs_tlv_desc_t *desc, ogs_tlv_t *tlv)
return OGS_OK;
}
/* rbtree structure used to keep track count of TLVs with given <type,instance>
* while parsing. This is used to link it to the matching nth field in a
* ogs_tlv_desc_t struct */
typedef struct tlv_count_node_s {
ogs_rbnode_t node;
uint32_t key; /* type<<8 + instance */
unsigned count;
} tlv_count_node_t;
static tlv_count_node_t *tlv_count_node_find(ogs_rbtree_t *tree, tlv_count_node_t *count_node_arr, unsigned count_node_arr_len,
unsigned *count_alloc_next, uint16_t type, uint8_t instance)
{
ogs_rbnode_t **new = NULL;
ogs_rbnode_t *parent = NULL;
tlv_count_node_t *this;
uint64_t key = (((uint32_t)type)<<8) | instance;
new = &tree->root;
while (*new) {
this = ogs_rb_entry(*new, tlv_count_node_t, node);
parent = *new;
if (key < this->key) {
new = &(*new)->left;
} else if (key > this->key) {
new = &(*new)->right;
} else { /* found entry: */
return this;
}
}
/* No entry, need to add one: */
if (*count_alloc_next == count_node_arr_len) {
ogs_error("This TLV has to many entries, can't parse");
return NULL;
}
this = &count_node_arr[(*count_alloc_next)++];
this->key = key;
this->count = 0;
ogs_rbtree_link_node(&this->node, parent, new);
ogs_rbtree_insert_color(tree, &this->node);
return this;
}
static int tlv_parse_compound(void *msg, ogs_tlv_desc_t *parent_desc,
ogs_tlv_t *parent_tlv, int depth, int mode)
{
@@ -438,6 +551,9 @@ static int tlv_parse_compound(void *msg, ogs_tlv_desc_t *parent_desc,
uint32_t offset = 0;
uint8_t index = 0;
int i = 0, j;
OGS_RBTREE(tree);
tlv_count_node_t count_node[OGS_TLV_MAX_CHILD_DESC];
unsigned count_node_alloc_next = 0;
char indent[17] = " "; /* 16 spaces */
ogs_assert(msg);
@@ -449,7 +565,11 @@ static int tlv_parse_compound(void *msg, ogs_tlv_desc_t *parent_desc,
tlv = parent_tlv;
while (tlv) {
desc = tlv_find_desc(&index, &offset, parent_desc, tlv);
tlv_count_node_t *curr_count = tlv_count_node_find(&tree, &count_node[0],
OGS_ARRAY_SIZE(count_node), &count_node_alloc_next, tlv->type, tlv->instance);
if (!curr_count)
return OGS_ERROR;
desc = tlv_find_desc_by_type_inst(&index, &offset, parent_desc, tlv->type, tlv->instance, curr_count->count);
if (desc == NULL) {
ogs_warn("Unknown TLV type [%d]", tlv->type);
tlv = tlv->next;
@@ -475,6 +595,8 @@ static int tlv_parse_compound(void *msg, ogs_tlv_desc_t *parent_desc,
tlv = tlv->next;
continue;
}
} else {
curr_count->count++;
}
if (desc->ctype == OGS_TLV_COMPOUND) {
@@ -544,3 +666,117 @@ int ogs_tlv_parse_msg(void *msg, ogs_tlv_desc_t *desc, ogs_pkbuf_t *pkbuf,
return rv;
}
static uint16_t parse_get_element_type(uint8_t *pos, uint8_t mode)
{
uint16_t type;
switch(mode) {
case OGS_TLV_MODE_T1_L1:
case OGS_TLV_MODE_T1_L2:
case OGS_TLV_MODE_T1_L2_I1:
case OGS_TLV_MODE_T1:
type = *pos;
break;
case OGS_TLV_MODE_T2_L2:
type = *(pos++) << 8;
type += *(pos++);
break;
default:
ogs_assert_if_reached();
break;
}
return type;
}
/* Get TLV element taking into account msg_mode (to know TLV tag length) +
* specific TLV information from "desc" (to know whether the specific IE is TLV
* or TV, and its expected length in the later case). */
static uint8_t *tlv_get_element_desc(ogs_tlv_t *tlv, uint8_t *blk, uint8_t msg_mode, ogs_tlv_desc_t *desc)
{
uint8_t instance;
unsigned tlv_tag_pos;
uint8_t desc_index = 0;
uint32_t tlv_offset = 0;
uint16_t tlv_tag;
uint8_t tlv_mode;
static ogs_tlv_desc_t* tlv_desc;
tlv_tag = parse_get_element_type(blk, msg_mode);
instance = 0; /* TODO: support instance != 0 if ever really needed by looking it up in pos */
tlv_tag_pos = 0; /* All tags with same instance should use the same tlv_desc, so take the first one */
tlv_desc = tlv_find_desc_by_type_inst(&desc_index, &tlv_offset, desc, tlv_tag, instance, tlv_tag_pos);
if (!tlv_desc) {
ogs_error("Can't parse find TLV description for type %u", tlv_tag);
return NULL;
}
tlv_mode = tlv_ctype2mode(tlv_desc->ctype, msg_mode);
if (tlv_mode == OGS_TLV_MODE_T1)
return tlv_get_element_fixed(tlv, blk, tlv_mode, tlv_desc->length);
return tlv_get_element(tlv, blk, tlv_mode);
}
/* Similar to ogs_tlv_parse_block(), but taking into account each TLV format from "desc". */
static ogs_tlv_t *ogs_tlv_parse_block_desc(uint32_t length, void *data, uint8_t msg_mode, ogs_tlv_desc_t *desc)
{
uint8_t *pos = data;
uint8_t *blk = data;
ogs_tlv_t *root = NULL;
ogs_tlv_t *prev = NULL;
ogs_tlv_t *curr = NULL;
root = curr = ogs_tlv_get();
ogs_assert(curr);
pos = tlv_get_element_desc(curr, pos, msg_mode, desc);
ogs_assert(pos);
while(pos - blk < length) {
prev = curr;
curr = ogs_tlv_get();
ogs_assert(curr);
prev->next = curr;
pos = tlv_get_element_desc(curr, pos, msg_mode, desc);
ogs_assert(pos);
}
ogs_assert(length == (pos - blk));
return root;
}
/* Similar to ogs_tlv_parse_msg(), but takes each TLV type from the desc
* defintion. This allows parsing messages which have different types of TLVs in
* it (for instance GTPv1-C). */
int ogs_tlv_parse_msg_desc(
void *msg, ogs_tlv_desc_t *desc, ogs_pkbuf_t *pkbuf, int msg_mode)
{
int rv;
ogs_tlv_t *root;
ogs_assert(msg);
ogs_assert(desc);
ogs_assert(pkbuf);
ogs_assert(desc->ctype == OGS_TLV_MESSAGE);
ogs_assert(desc->child_descs[0]);
root = ogs_tlv_parse_block_desc(pkbuf->len, pkbuf->data, msg_mode, desc);
if (root == NULL) {
ogs_error("Can't parse TLV message");
return OGS_ERROR;
}
rv = tlv_parse_compound(msg, desc, root, 0, msg_mode);
ogs_tlv_free_all(root);
return rv;
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* This file is part of Open5GS.
*
@@ -50,6 +51,18 @@ typedef enum {
OGS_TLV_MORE,
OGS_TLV_COMPOUND,
OGS_TLV_MESSAGE,
OGS_TV_UINT8,
OGS_TV_UINT16,
OGS_TV_UINT24,
OGS_TV_UINT32,
OGS_TV_INT8,
OGS_TV_INT16,
OGS_TV_INT24,
OGS_TV_INT32,
OGS_TV_FIXED_STR,
OGS_TV_VAR_STR,
OGS_TV_NULL,
OGS_TV_MORE,
} ogs_tlv_type_e;
typedef struct ogs_tlv_desc_s {
@@ -158,6 +171,8 @@ typedef struct ogs_tlv_null_s {
ogs_pkbuf_t *ogs_tlv_build_msg(ogs_tlv_desc_t *desc, void *msg, int mode);
int ogs_tlv_parse_msg(
void *msg, ogs_tlv_desc_t *desc, ogs_pkbuf_t *pkbuf, int mode);
int ogs_tlv_parse_msg_desc(
void *msg, ogs_tlv_desc_t *desc, ogs_pkbuf_t *pkbuf, int msg_mode);
#ifdef __cplusplus
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* This file is part of Open5GS.
*
@@ -105,14 +106,14 @@ uint32_t ogs_tlv_value_32(ogs_tlv_t *tlv)
return u_32;
}
uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv, uint8_t mode)
uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv)
{
ogs_tlv_t *iter = tlv;
uint32_t length = 0;
while(iter) {
/* this is length for type field */
switch(mode) {
switch(iter->mode) {
case OGS_TLV_MODE_T1_L1:
length += 2;
break;
@@ -123,6 +124,9 @@ uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv, uint8_t mode)
case OGS_TLV_MODE_T2_L2:
length += 4;
break;
case OGS_TLV_MODE_T1:
length += 1;
break;
default:
ogs_assert_if_reached();
break;
@@ -130,7 +134,7 @@ uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv, uint8_t mode)
/* this is length for type field */
if(iter->embedded != NULL) {
iter->length = ogs_tlv_calc_length(iter->embedded, mode);
iter->length = ogs_tlv_calc_length(iter->embedded);
}
/* this is length for value field */
@@ -163,6 +167,7 @@ static uint8_t *tlv_put_type(uint32_t type, uint8_t *pos, uint8_t mode)
case OGS_TLV_MODE_T1_L1:
case OGS_TLV_MODE_T1_L2:
case OGS_TLV_MODE_T1_L2_I1:
case OGS_TLV_MODE_T1:
*(pos++) = type & 0xFF;
break;
case OGS_TLV_MODE_T2_L2:
@@ -188,6 +193,8 @@ static uint8_t *tlv_put_length(uint32_t length, uint8_t *pos, uint8_t mode)
*(pos++) = (length >> 8) & 0xFF;
*(pos++) = length & 0xFF;
break;
case OGS_TLV_MODE_T1:
break;
default:
ogs_assert_if_reached();
break;
@@ -209,10 +216,12 @@ static uint8_t *tlv_put_instance(uint8_t instance, uint8_t *pos, uint8_t mode)
return pos;
}
static uint8_t *tlv_get_element(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode)
uint8_t *tlv_get_element(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode)
{
uint8_t *pos = blk;
tlv->mode = mode;
switch(mode) {
case OGS_TLV_MODE_T1_L1:
tlv->type = *(pos++);
@@ -235,6 +244,29 @@ static uint8_t *tlv_get_element(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode)
tlv->length = *(pos++) << 8;
tlv->length += *(pos++);
break;
case OGS_TLV_MODE_T1:
tlv->type = *(pos++);
tlv->length = 0;
break;
default:
ogs_assert_if_reached();
break;
}
tlv->value = pos;
return (pos + ogs_tlv_length(tlv));
}
uint8_t *tlv_get_element_fixed(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode, uint32_t fixed_length)
{
uint8_t *pos = blk;
switch(mode) {
case OGS_TLV_MODE_T1:
tlv->type = *(pos++);
tlv->length = fixed_length;
break;
default:
ogs_assert_if_reached();
break;
@@ -268,7 +300,7 @@ ogs_tlv_t *ogs_tlv_find_root(ogs_tlv_t *tlv)
return head;
}
ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head,
ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value)
{
ogs_tlv_t *curr = head;
@@ -279,6 +311,7 @@ ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head,
if(length != 0)
ogs_assert(value);
new->mode = mode;
new->type = type;
new->length = length;
new->instance = instance;
@@ -304,7 +337,7 @@ ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head,
return new;
}
ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len,
ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value)
{
ogs_tlv_t *new = NULL;
@@ -312,6 +345,7 @@ ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len,
new = ogs_tlv_get();
ogs_assert(new);
new->mode = mode;
new->type = type;
new->length = length;
new->instance = instance;
@@ -327,7 +361,7 @@ ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len,
return new;
}
ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent,
ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value)
{
ogs_tlv_t *new = NULL, *root = NULL;
@@ -337,6 +371,7 @@ ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent,
new = ogs_tlv_get();
ogs_assert(new);
new->mode = mode;
new->type = type;
new->length = length;
new->instance = instance;
@@ -364,8 +399,7 @@ ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent,
return new;
}
uint32_t ogs_tlv_render(ogs_tlv_t *root,
void *data, uint32_t length, uint8_t mode)
uint32_t ogs_tlv_render(ogs_tlv_t *root, void *data, uint32_t length)
{
ogs_tlv_t *curr = root;
uint8_t *pos = data;
@@ -373,11 +407,11 @@ uint32_t ogs_tlv_render(ogs_tlv_t *root,
uint32_t embedded_len = 0;
while(curr) {
pos = tlv_put_type(curr->type, pos, mode);
pos = tlv_put_type(curr->type, pos, curr->mode);
if(curr->embedded == NULL) {
pos = tlv_put_length(curr->length, pos, mode);
pos = tlv_put_instance(curr->instance, pos, mode);
pos = tlv_put_length(curr->length, pos, curr->mode);
pos = tlv_put_instance(curr->instance, pos, curr->mode);
if ((pos - blk) + ogs_tlv_length(curr) > length)
ogs_assert_if_reached();
@@ -385,11 +419,11 @@ uint32_t ogs_tlv_render(ogs_tlv_t *root,
memcpy((char*)pos, (char*)curr->value, curr->length);
pos += curr->length;
} else {
embedded_len = ogs_tlv_calc_length(curr->embedded, mode);
pos = tlv_put_length(embedded_len, pos, mode);
pos = tlv_put_instance(curr->instance, pos, mode);
embedded_len = ogs_tlv_calc_length(curr->embedded);
pos = tlv_put_length(embedded_len, pos, curr->mode);
pos = tlv_put_instance(curr->instance, pos, curr->mode);
ogs_tlv_render(curr->embedded,
pos, length - (uint32_t)(pos-blk), mode);
pos, length - (uint32_t)(pos-blk));
pos += embedded_len;
}
curr = curr->next;

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* This file is part of Open5GS.
*
@@ -32,6 +33,7 @@ extern "C" {
#define OGS_TLV_MODE_T1_L2 2
#define OGS_TLV_MODE_T1_L2_I1 3
#define OGS_TLV_MODE_T2_L2 4
#define OGS_TLV_MODE_T1 5
/* ogs_tlv_t struncture */
@@ -45,6 +47,9 @@ typedef struct ogs_tlv_s
struct ogs_tlv_s *parent;
struct ogs_tlv_s *embedded;
/* tlv mode: defines exact meaning and (conditional) use of fields in next section */
uint8_t mode;
/* tlv basic element */
uint32_t type;
uint32_t length;
@@ -74,24 +79,25 @@ void ogs_tlv_final(void);
uint32_t ogs_tlv_pool_avail(void);
/* ogs_tlv_t encoding functions */
ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head,
ogs_tlv_t *ogs_tlv_add(ogs_tlv_t *head, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value);
ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len,
ogs_tlv_t *ogs_tlv_copy(void *buff, uint32_t buff_len, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value);
ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent,
ogs_tlv_t *ogs_tlv_embed(ogs_tlv_t *parent, uint8_t mode,
uint32_t type, uint32_t length, uint8_t instance, void *value);
uint32_t ogs_tlv_render(
ogs_tlv_t *root, void *data, uint32_t length, uint8_t mode);
uint32_t ogs_tlv_render(ogs_tlv_t *root, void *data, uint32_t length);
/* ogs_tlv_t parsing functions */
uint8_t *tlv_get_element(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode);
uint8_t *tlv_get_element_fixed(ogs_tlv_t *tlv, uint8_t *blk, uint8_t mode, uint32_t fixed_length);
ogs_tlv_t *ogs_tlv_parse_block(uint32_t length, void *data, uint8_t mode);
ogs_tlv_t *ogs_tlv_parse_embedded_block(ogs_tlv_t *tlv, uint8_t mode);
/* tlv operation-related function */
ogs_tlv_t *ogs_tlv_find(ogs_tlv_t *root, uint32_t type);
ogs_tlv_t *ogs_tlv_find_root(ogs_tlv_t *tlv);
uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv, uint8_t mode);
uint32_t ogs_tlv_calc_length(ogs_tlv_t *tlv);
uint32_t ogs_tlv_calc_count(ogs_tlv_t *tlv);
uint8_t ogs_tlv_value_8(ogs_tlv_t *tlv);
uint16_t ogs_tlv_value_16(ogs_tlv_t *tlv);

View File

@@ -22,66 +22,76 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node)
ogs_sock_t *ogs_udp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *sock = NULL;
sock = ogs_sock_socket(family, SOCK_DGRAM, IPPROTO_UDP);
ogs_assert(sock);
ogs_debug("udp_socket() family:%d", family);
return sock;
}
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_udp_socket(addr->ogs_sa_family, node);
if (new) {
if (ogs_sock_bind(new, addr) == OGS_OK) {
ogs_debug("udp_server() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
break;
}
ogs_sock_destroy(new);
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (!new) {
addr = addr->next;
continue;
}
addr = addr->next;
if (ogs_sock_bind(new, addr) != OGS_OK) {
ogs_sock_destroy(new);
addr = addr->next;
continue;
}
ogs_debug("udp_server() [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr));
if (option.so_bindtodevice) {
if (ogs_bind_to_device(new->fd, option.so_bindtodevice) != OGS_OK) {
ogs_sock_destroy(new);
addr = addr->next;
continue;
}
ogs_info("udp_server() [%s]:%d bound to device `%s`",
OGS_ADDR(addr, buf), OGS_PORT(addr),
option.so_bindtodevice);
}
break;
}
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"udp_server() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = new;
return new;
}
ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
ogs_sock_t *ogs_udp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
addr = node->addr;
ogs_sockopt_t option;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_udp_socket(addr->ogs_sa_family, node);
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (new) {
if (ogs_sock_connect(new, addr) == OGS_OK) {
ogs_debug("udp_client() [%s]:%d",
@@ -98,12 +108,10 @@ ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"udp_client() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;;
}
node->sock = new;
return new;
}

View File

@@ -28,9 +28,10 @@
extern "C" {
#endif
ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node);
ogs_sock_t *ogs_udp_client(ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_udp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
int ogs_udp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
#ifdef __cplusplus

View File

@@ -60,9 +60,9 @@ static char *masked_db_uri(const char *db_uri)
ogs_assert(tmp);
memset(array, 0, sizeof(array));
array[0] = strtok_r(tmp, "@", &saveptr);
array[0] = ogs_strtok_r(tmp, "@", &saveptr);
if (array[0])
array[1] = strtok_r(NULL, "@", &saveptr);
array[1] = ogs_strtok_r(NULL, "@", &saveptr);
if (array[1]) {
masked = ogs_msprintf("mongodb://*****:*****@%s", array[1]);

View File

@@ -148,6 +148,47 @@ int ogs_dbi_update_sqn(char *supi, uint64_t sqn)
return rv;
}
int ogs_dbi_update_imeisv(char *supi, char *imeisv)
{
int rv = OGS_OK;
bson_t *query = NULL;
bson_t *update = NULL;
bson_error_t error;
char *supi_type = NULL;
char *supi_id = NULL;
ogs_assert(supi);
supi_type = ogs_id_get_type(supi);
ogs_assert(supi_type);
supi_id = ogs_id_get_value(supi);
ogs_assert(supi_id);
ogs_debug("SUPI type: %s, SUPI id: %s, imeisv: %s",
supi_type, supi_id, imeisv);
query = BCON_NEW(supi_type, BCON_UTF8(supi_id));
update = BCON_NEW("$set",
"{",
"imeisv", BCON_UTF8(imeisv),
"}");
if (!mongoc_collection_update(ogs_mongoc()->collection.subscriber,
MONGOC_UPDATE_UPSERT, query, update, NULL, &error)) {
ogs_error("mongoc_collection_update() failure: %s", error.message);
rv = OGS_ERROR;
}
if (query) bson_destroy(query);
if (update) bson_destroy(update);
ogs_free(supi_type);
ogs_free(supi_id);
return rv;
}
int ogs_dbi_increment_sqn(char *supi)
{
int rv = OGS_OK;

View File

@@ -41,6 +41,7 @@ typedef struct ogs_dbi_auth_info_s {
int ogs_dbi_auth_info(char *supi, ogs_dbi_auth_info_t *auth_info);
int ogs_dbi_update_sqn(char *supi, uint64_t sqn);
int ogs_dbi_increment_sqn(char *supi);
int ogs_dbi_update_imeisv(char *supi, char *imeisv);
int ogs_dbi_subscription_data(char *supi,
ogs_subscription_data_t *subscription_data);

View File

@@ -28,13 +28,13 @@
extern "C" {
#endif
/* This is default diameter configuration if there is no config file
/* This is default diameter configuration if there is no config file
* The Configuration : No TLS, Only TCP */
typedef struct ogs_diam_config_s {
/* Diameter Identity of the local peer (FQDN -- ASCII) */
const char *cnf_diamid;
const char *cnf_diamid;
/* Diameter realm of the local peer, default to realm part of cnf_diamid */
const char *cnf_diamrlm;
const char *cnf_diamrlm;
/* IP address of the local peer */
const char *cnf_addr;
@@ -58,10 +58,10 @@ typedef struct ogs_diam_config_s {
int num_of_ext;
#define MAX_NUM_OF_FD_CONN 16
/* (supposedly) UTF-8, \0 terminated.
/* (supposedly) UTF-8, \0 terminated.
* The Diameter Identity of the remote peer. */
struct {
const char *identity;
const char *identity;
const char *addr; /* IP address of the remote peer */
uint16_t port; /* port to connect to. 0: default. */
} conn[MAX_NUM_OF_FD_CONN];
@@ -75,7 +75,7 @@ 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);
int fd_avp_search_avp ( struct avp * groupedavp,
int fd_avp_search_avp ( struct avp * groupedavp,
struct dict_object * what, struct avp ** avp );
#ifdef __cplusplus

View File

@@ -23,11 +23,14 @@
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct dict_object *ogs_diam_session_id = NULL;
struct dict_object *ogs_diam_termination_cause = NULL;
struct dict_object *ogs_diam_origin_host = NULL;
struct dict_object *ogs_diam_origin_realm = NULL;
struct dict_object *ogs_diam_destination_host = NULL;
struct dict_object *ogs_diam_destination_realm = NULL;
struct dict_object *ogs_diam_user_name = NULL;
struct dict_object *ogs_diam_origin_state_id = NULL;
struct dict_object *ogs_diam_event_timestamp = NULL;
struct dict_object *ogs_diam_subscription_id = NULL;
struct dict_object *ogs_diam_subscription_id_type = NULL;
struct dict_object *ogs_diam_subscription_id_data = NULL;
@@ -44,6 +47,7 @@ struct dict_object *ogs_diam_mip_home_agent_address = NULL;
struct dict_object *ogs_diam_authorization_lifetime = NULL;
struct dict_object *ogs_diam_auth_grace_period = NULL;
struct dict_object *ogs_diam_session_timeout = NULL;
struct dict_object *ogs_diam_service_context_id = NULL;
struct dict_object *ogs_diam_rat_type = NULL;
struct dict_object *ogs_diam_service_selection = NULL;
struct dict_object *ogs_diam_visited_plmn_id = NULL;
@@ -64,11 +68,14 @@ int ogs_diam_message_init()
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Vendor-Id", &ogs_diam_vendor_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Session-Id", &ogs_diam_session_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME, "Termination-Cause", &ogs_diam_termination_cause);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Host", &ogs_diam_origin_host);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Origin-Realm", &ogs_diam_origin_realm);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Host", &ogs_diam_destination_host);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Destination-Realm", &ogs_diam_destination_realm);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "User-Name", &ogs_diam_user_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME, "Origin-State-Id", &ogs_diam_origin_state_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME, "Event-Timestamp", &ogs_diam_event_timestamp);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Subscription-Id", &ogs_diam_subscription_id);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Subscription-Id-Type", &ogs_diam_subscription_id_type);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Subscription-Id-Data", &ogs_diam_subscription_id_data);
@@ -85,6 +92,7 @@ int ogs_diam_message_init()
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Authorization-Lifetime", &ogs_diam_authorization_lifetime);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Auth-Grace-Period", &ogs_diam_auth_grace_period);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Session-Timeout", &ogs_diam_session_timeout);
CHECK_dict_search( DICT_AVP, AVP_BY_NAME, "Service-Context-Id", &ogs_diam_service_context_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "RAT-Type", &ogs_diam_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Selection", &ogs_diam_service_selection);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Visited-PLMN-Id", &ogs_diam_visited_plmn_id);
@@ -101,13 +109,13 @@ int ogs_diam_message_session_id_set(
/* Create an AVP to hold it */
CHECK_FCT( fd_msg_avp_new( ogs_diam_session_id, 0, &avp ) );
/* Set its value */
memset(&val, 0, sizeof(val));
val.os.data = sid;
val.os.len = sidlen;
CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) );
/* Add it to the message */
CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) );
@@ -162,7 +170,7 @@ int ogs_diam_message_vendor_specific_appid_set(struct msg *msg, uint32_t app_id)
value.u32 = app_id;
CHECK_FCT(
fd_msg_avp_setvalue(avp_vendor_specific_application_id, &value) );
CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
CHECK_FCT( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
avp_vendor_specific_application_id) );
CHECK_FCT( fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp) );

View File

@@ -42,11 +42,22 @@ extern "C" {
#define OGS_DIAM_INVALID_AVP_VALUE 5005
extern struct dict_object *ogs_diam_session_id;
extern struct dict_object *ogs_diam_termination_cause;
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_LOGOUT 1
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_SERVICE_NOT_PROVIDED 2
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_BAD_ANSWER 3
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_DIAMETER_ADMINISTRATIVE 4
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_LINK_BROKEN 5
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_AUTH_EXPIRED 6
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_USER_MOVED 7
#define OGS_DIAM_TERMINATION_CAUSE_DIAMETER_SESSION_TIMEOUT 8
extern struct dict_object *ogs_diam_origin_host;
extern struct dict_object *ogs_diam_origin_realm;
extern struct dict_object *ogs_diam_destination_host;
extern struct dict_object *ogs_diam_destination_realm;
extern struct dict_object *ogs_diam_user_name;
extern struct dict_object *ogs_diam_origin_state_id;
extern struct dict_object *ogs_diam_event_timestamp;
extern struct dict_object *ogs_diam_subscription_id;
#define OGS_DIAM_SUBSCRIPTION_ID_TYPE_END_USER_E164 0
#define OGS_DIAM_SUBSCRIPTION_ID_TYPE_END_USER_IMSI 1
@@ -74,6 +85,7 @@ extern struct dict_object *ogs_diam_mip_home_agent_address;
extern struct dict_object *ogs_diam_authorization_lifetime;
extern struct dict_object *ogs_diam_auth_grace_period;
extern struct dict_object *ogs_diam_session_timeout;
extern struct dict_object *ogs_diam_service_context_id;
#define OGS_DIAM_RAT_TYPE_WLAN 0
#define OGS_DIAM_RAT_TYPE_VIRTUAL 1
#define OGS_DIAM_RAT_TYPE_UTRAN 1000

View File

@@ -29,7 +29,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
/*
/*
* Dictionary definitions for objects specified for DCCA by 3GPP.
*
* This extensions contains a lot of AVPs from various 3GPP standards
@@ -87,6 +87,7 @@
* uses some AVPs from the former, but not this one.
*/
#include <freeDiameter/extension.h>
#include "ogs-diameter-gx.h"
/* The content of this file follows the same structure as dict_base_proto.c */
@@ -145,11 +146,11 @@ struct local_rules_definition {
int ogs_dict_gx_entry(char *conffile)
{
/* Applications section */
{
{
{
struct dict_object * vendor;
CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor, ENOENT));
struct dict_application_data app_data = { 16777238, "Gx" };
struct dict_application_data app_data = { OGS_DIAM_GX_APPLICATION_ID, "Gx" };
CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_APPLICATION, &app_data, vendor, NULL));
}
@@ -276,7 +277,7 @@ int ogs_dict_gx_entry(char *conffile)
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd);
PARSE_loc_rules( rules, cmd );
}
LOG_D( "Extension 'Dictionary definitions for DCCA 3GPP' initialized");
return 0;
}

238
lib/diameter/gy/dict.c Normal file
View File

@@ -0,0 +1,238 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Thomas Klausner <tk@giga.or.at> *
* *
* Copyright (c) 2013, Thomas Klausner *
* All rights reserved. *
* *
* Written under contract by nfotex IT GmbH, http://nfotex.com/ *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
/*
* Dictionary definitions for objects specified for DCCA by 3GPP.
*
* This extensions contains a lot of AVPs from various 3GPP standards
* documents, and some rules for the grouped AVPs described therein.
*
* This extension does not contain ALL AVPs described by 3GPP, but
* quite a big number of them.
*
* When extending the AVPs, please edit dict_rx.org instead and
* create pastable code with contrib/tools/org_to_fd.pl.
*
* Some points of consideration:
* 1. This dictionary could be split up per document.
*
* + pro: you can only load the AVPs/Rules you're interested in ->
* smaller memory size
*
* - con: the documents use AVPs from each other A LOT, so setting the
* dependencies correctly will be annoying
*
* - con: you need to load all of them as extensions
*
* 2. This dictionary contains ONE AVP in the "3GPP2" vendor space,
* since I found it wasteful to write a separate dictionary just for
* one AVP. Also, it is defined in a 3GPP document.
*
* 3. While there are quite a number of rules here already, many more
* are missing. I've only added rules for those grouped AVPs or
* commands in which I was concretely interested so far; many more
* will need to be added to make this complete.
*
* That being said, I hope this will be useful for you.
*
*/
/*
* Some comments on the 3GPP Standards documents themselves:
*
* 1. It would be good if 29.061 was reviewed to check for each AVP if
* it is Mandatory or not. The data currently in the document does not
* match what was in the previous version of the freeDiameter
* extension (the one that existedbefore I rewrote it) or what I saw
* so far. IIRC, even the table and the document contradict each
* other. The AVP table is also missing an entry for
* "External-Identifier", 28.
*
* 2. 29.140 has conflicting AVP names with other documents:
* - Sequence-Number is also in 32.329
* - Recipient-Address is also in 32.299
* - Status is also in 32.299
*
* 3. 29.229 has name conflict with 29.329 about User-Data (different
* AVP code 702, instead of 606) -- the weird thing is, the latter
* uses some AVPs from the former, but not this one.
*/
#include <freeDiameter/extension.h>
#include "ogs-diameter-gy.h"
/* The content of this file follows the same structure as dict_base_proto.c */
#define CHECK_dict_new( _type, _data, _parent, _ref ) \
CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct local_rules_definition {
struct dict_avp_request avp_vendor_plus_name;
enum rule_position position;
int min;
int max;
};
#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
#define PARSE_loc_rules( _rulearray, _parent) { \
int __ar; \
for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
struct dict_rule_data __data = { NULL, \
(_rulearray)[__ar].position, \
0, \
(_rulearray)[__ar].min, \
(_rulearray)[__ar].max}; \
__data.rule_order = RULE_ORDER(__data.rule_position); \
CHECK_FCT( fd_dict_search( \
fd_g_config->cnf_dict, \
DICT_AVP, \
AVP_BY_NAME_AND_VENDOR, \
&(_rulearray)[__ar].avp_vendor_plus_name, \
&__data.rule_avp, 0 ) ); \
if ( !__data.rule_avp ) { \
TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
return ENOENT; \
} \
CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
{ \
TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
(_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
return EINVAL; \
} ); \
} \
}
#define enumval_def_u32( _val_, _str_ ) \
{ _str_, { .u32 = _val_ }}
#define enumval_def_os( _len_, _val_, _str_ ) \
{ _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
int ogs_dict_gy_entry(char *conffile)
{
/* Applications section */
{
{
//struct dict_object * vendor;
//CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor, ENOENT));
struct dict_application_data app_data = { OGS_DIAM_GY_APPLICATION_ID, "Gy" };
CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_APPLICATION, &app_data, NULL, NULL));
}
}
/* Credit-Control-Request (CCR) Command - Extension for Gy (3GPP TS 32.299 sec 6.4.2) */
{
struct dict_object * cmd;
struct local_rules_definition rules[] =
{
{ { .avp_name = "Session-Id" }, RULE_FIXED_HEAD, -1, 1 },
{ { .avp_name = "Origin-Host" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Destination-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Auth-Application-Id" }, RULE_REQUIRED, -1, 1 },
//{ { .avp_name = "Service-Context-Id" }, RULE_REQUIRED, -1, 1 }, /* freeDiameter: Conflicting rule position */
{ { .avp_name = "CC-Request-Type" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "CC-Request-Number" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Destination-Host" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "User-Name" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Origin-State-Id" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Event-Timestamp" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Subscription-Id" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Termination-Cause" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Requested-Action" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "AoC-Request-Type" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Multiple-Services-Indicator" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Multiple-Services-Credit-Control" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "CC-Correlation-Id" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "User-Equipment-Info" }, RULE_OPTIONAL, -1, 1 },
//{ { .avp_name = "OC-Supported-Features" }, RULE_OPTIONAL, -1, 1 }, /*freeDiameter: AVP Not found: 'OC-Supported-Features' */
{ { .avp_name = "Proxy-Info" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Route-Record" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_vendor = 10415, .avp_name = "Service-Information" }, RULE_OPTIONAL, -1, 1 },
/* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
};
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &cmd);
PARSE_loc_rules( rules, cmd );
}
/* Credit-Control-Answer (CCA) Command - Extension for Gy (3GPP TS 32.299 sec 6.4.3) */
{
struct dict_object * cmd;
struct local_rules_definition rules[] =
{
{ { .avp_name = "Session-Id" }, RULE_FIXED_HEAD, -1, 1 },
{ { .avp_name = "Result-Code" }, RULE_REQUIRED, -1, 1 },
// { { .avp_name = "Experimental-Result" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Origin-Host" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Origin-Realm" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "Auth-Application-Id" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "CC-Request-Type" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "CC-Request-Number" }, RULE_REQUIRED, -1, 1 },
{ { .avp_name = "CC-Session-Failover" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Multiple-Services-Credit-Control" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Cost-Information" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Low-Balance-Indication" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_vendor = 10415, .avp_name = "Remaining-Balance" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Credit-Control-Failure-Handling" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Direct-Debiting-Failure-Handling" }, RULE_OPTIONAL, -1, 1 },
//{ { .avp_name = "OC-Supported-Features" }, RULE_OPTIONAL, -1, 1 }, /*freeDiameter: AVP Not found: 'OC-Supported-Features' */
//{ { .avp_name = "OC-OLR" }, RULE_OPTIONAL, -1, 1 }, /*freeDiameter: AVP Not found: 'OC-OLR' */
{ { .avp_name = "Redirect-Host" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Redirect-Host-Usage" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Redirect-Max-Cache-Time" }, RULE_OPTIONAL, -1, 1 },
{ { .avp_name = "Proxy-Info" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Route-Record" }, RULE_OPTIONAL, -1, -1 },
{ { .avp_name = "Failed-AVP" }, RULE_OPTIONAL, -1, -1 }, /* 3GPP TS 32.299 6.4.3 says max=1 but RFC4006 & freeDiameter says max=-1 */
{ { .avp_vendor = 10415, .avp_name = "Service-Information" }, RULE_OPTIONAL, -1, 1 },
/* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
};
CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd);
PARSE_loc_rules( rules, cmd );
}
LOG_D( "Extension 'Dictionary definitions for 3GPP Gy' initialized");
return 0;
}
#if 0 /* modified by acetcom */
EXTENSION_ENTRY("dict_gy", ogs_dict_gy_entry, "dict_dcca_3gpp");
#endif

View File

@@ -0,0 +1,41 @@
# Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
# Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
# 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 <https://www.gnu.org/licenses/>.
libdiameter_gy_sources = files('''
ogs-diameter-gy.h
message.h
dict.c
message.c
'''.split())
libdiameter_gy_inc = include_directories('.')
libdiameter_gy = library('ogsdiameter-gy',
sources : libdiameter_gy_sources,
version : libogslib_version,
c_args : libdiameter_common_cc_flags,
include_directories : libdiameter_gy_inc,
dependencies : libdiameter_common_dep,
install : true)
libdiameter_gy_dep = declare_dependency(
link_with : libdiameter_gy,
include_directories : libdiameter_gy_inc,
dependencies : libdiameter_common_dep)

155
lib/diameter/gy/message.c Normal file
View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "ogs-diameter-gy.h"
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct dict_object *ogs_diam_gy_application = NULL;
struct dict_object *ogs_diam_gy_cmd_ccr = NULL;
struct dict_object *ogs_diam_gy_cmd_cca = NULL;
struct dict_object *ogs_diam_gy_cmd_rar = NULL;
struct dict_object *ogs_diam_gy_cmd_raa = NULL;
struct dict_object *ogs_diam_gy_cc_request_type = NULL;
struct dict_object *ogs_diam_gy_cc_request_number = NULL;
struct dict_object *ogs_diam_gy_requested_action = NULL;
struct dict_object *ogs_diam_gy_aoc_request_type = NULL;
struct dict_object *ogs_diam_gy_multiple_services_ind = NULL;
struct dict_object *ogs_diam_gy_multiple_services_cc = NULL;
struct dict_object *ogs_diam_gy_requested_service_unit = NULL;
struct dict_object *ogs_diam_gy_used_service_unit = NULL;
struct dict_object *ogs_diam_gy_cc_time = NULL;
struct dict_object *ogs_diam_gy_cc_total_octets = NULL;
struct dict_object *ogs_diam_gy_cc_input_octets = NULL;
struct dict_object *ogs_diam_gy_cc_output_octets = NULL;
struct dict_object *ogs_diam_gy_cc_service_specific_units = NULL;
struct dict_object *ogs_diam_gy_reporting_reason = NULL;
struct dict_object *ogs_diam_gy_service_id = NULL;
struct dict_object *ogs_diam_gy_service_information = NULL;
struct dict_object *ogs_diam_gy_ps_information = NULL;
struct dict_object *ogs_diam_gy_3gpp_charging_id = NULL;
struct dict_object *ogs_diam_gy_3gpp_pdp_type = NULL;
struct dict_object *ogs_diam_gy_pdp_address = NULL;
struct dict_object *ogs_diam_gy_sgsn_address = NULL;
struct dict_object *ogs_diam_gy_ggsn_address = NULL;
struct dict_object *ogs_diam_gy_3gpp_nsapi = NULL;
struct dict_object *ogs_diam_gy_3gpp_selection_mode = NULL;
struct dict_object *ogs_diam_gy_3gpp_charging_characteristics = NULL;
struct dict_object *ogs_diam_gy_user_equipment_info = NULL;
struct dict_object *ogs_diam_gy_user_equipment_info_type = NULL;
struct dict_object *ogs_diam_gy_user_equipment_info_value = NULL;
struct dict_object *ogs_diam_gy_feature_list_id = NULL;
struct dict_object *ogs_diam_gy_feature_list = NULL;
struct dict_object *ogs_diam_gy_qos_information = NULL;
struct dict_object *ogs_diam_gy_qos_class_identifier = NULL;
struct dict_object *ogs_diam_gy_max_requested_bandwidth_ul = NULL;
struct dict_object *ogs_diam_gy_max_requested_bandwidth_dl = NULL;
struct dict_object *ogs_diam_gy_guaranteed_bitrate_ul = NULL;
struct dict_object *ogs_diam_gy_guaranteed_bitrate_dl = NULL;
struct dict_object *ogs_diam_gy_allocation_retention_priority = NULL;
struct dict_object *ogs_diam_gy_priority_level = NULL;
struct dict_object *ogs_diam_gy_pre_emption_capability = NULL;
struct dict_object *ogs_diam_gy_pre_emption_vulnerability = NULL;
struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_ul = NULL;
struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_dl = NULL;
struct dict_object *ogs_diam_gy_3gpp_rat_type = NULL;
struct dict_object *ogs_diam_gy_3gpp_user_location_info = NULL;
struct dict_object *ogs_diam_gy_called_station_id = NULL;
struct dict_object *ogs_diam_gy_3gpp_ms_timezone = NULL;
struct dict_object *ogs_diam_gy_charging_rule_base_name = NULL;
struct dict_object *ogs_diam_gy_flows = NULL;
struct dict_object *ogs_diam_gy_3gpp_sgsn_mcc_mnc = NULL;
extern int ogs_dict_gy_entry(char *conffile);
int ogs_diam_gy_init(void)
{
application_id_t id = OGS_DIAM_GY_APPLICATION_ID;
ogs_assert(ogs_dict_gy_entry(NULL) == 0);
CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID, (void *)&id, &ogs_diam_gy_application);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &ogs_diam_gy_cmd_ccr);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &ogs_diam_gy_cmd_cca);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &ogs_diam_gy_cmd_rar);
CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &ogs_diam_gy_cmd_raa);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Type", &ogs_diam_gy_cc_request_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Request-Number", &ogs_diam_gy_cc_request_number);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Requested-Action", &ogs_diam_gy_requested_action);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "AoC-Request-Type", &ogs_diam_gy_aoc_request_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Multiple-Services-Indicator", &ogs_diam_gy_multiple_services_ind);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Multiple-Services-Credit-Control", &ogs_diam_gy_multiple_services_cc);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Requested-Service-Unit", &ogs_diam_gy_requested_service_unit);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Used-Service-Unit", &ogs_diam_gy_used_service_unit);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Time", &ogs_diam_gy_cc_time);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Total-Octets", &ogs_diam_gy_cc_total_octets);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Input-Octets", &ogs_diam_gy_cc_input_octets);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Output-Octets", &ogs_diam_gy_cc_output_octets);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "CC-Service-Specific-Units", &ogs_diam_gy_cc_service_specific_units);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Reporting-Reason", &ogs_diam_gy_reporting_reason);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Identifier", &ogs_diam_gy_service_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Information", &ogs_diam_gy_service_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PS-Information", &ogs_diam_gy_ps_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Charging-Id", &ogs_diam_gy_3gpp_charging_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-PDP-Type", &ogs_diam_gy_3gpp_pdp_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDP-Address", &ogs_diam_gy_pdp_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "SGSN-Address", &ogs_diam_gy_sgsn_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "GGSN-Address", &ogs_diam_gy_ggsn_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-NSAPI", &ogs_diam_gy_3gpp_nsapi);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Selection-Mode", &ogs_diam_gy_3gpp_selection_mode);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Charging-Characteristics", &ogs_diam_gy_3gpp_charging_characteristics);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "User-Equipment-Info", &ogs_diam_gy_user_equipment_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "User-Equipment-Info-Type", &ogs_diam_gy_user_equipment_info_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "User-Equipment-Info-Value", &ogs_diam_gy_user_equipment_info_value);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &ogs_diam_gy_feature_list_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &ogs_diam_gy_feature_list);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Information", &ogs_diam_gy_qos_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Class-Identifier" , &ogs_diam_gy_qos_class_identifier);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-UL" , &ogs_diam_gy_max_requested_bandwidth_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Max-Requested-Bandwidth-DL" , &ogs_diam_gy_max_requested_bandwidth_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Guaranteed-Bitrate-UL" , &ogs_diam_gy_guaranteed_bitrate_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Guaranteed-Bitrate-DL" , &ogs_diam_gy_guaranteed_bitrate_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Allocation-Retention-Priority" , &ogs_diam_gy_allocation_retention_priority);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Priority-Level", &ogs_diam_gy_priority_level);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Capability", &ogs_diam_gy_pre_emption_capability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Pre-emption-Vulnerability", &ogs_diam_gy_pre_emption_vulnerability);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Aggregate-Max-Bitrate-UL" , &ogs_diam_gy_apn_aggregate_max_bitrate_ul);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Aggregate-Max-Bitrate-DL" , &ogs_diam_gy_apn_aggregate_max_bitrate_dl);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-RAT-Type" , &ogs_diam_gy_3gpp_rat_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-User-Location-Info", &ogs_diam_gy_3gpp_user_location_info);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Called-Station-Id", &ogs_diam_gy_called_station_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-MS-TimeZone", &ogs_diam_gy_3gpp_ms_timezone);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Charging-Rule-Base-Name", &ogs_diam_gy_charging_rule_base_name);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Flows", &ogs_diam_gy_flows);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-SGSN-MCC-MNC", &ogs_diam_gy_3gpp_sgsn_mcc_mnc);
return 0;
}

200
lib/diameter/gy/message.h Normal file
View File

@@ -0,0 +1,200 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_DIAMETER_INSIDE) && !defined(OGS_DIAMETER_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_DIAM_GY_MESSAGE_H
#define OGS_DIAM_GY_MESSAGE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Gy interface, 3GPP TS 32.299 */
#define OGS_DIAM_GY_APPLICATION_ID 4
#define OGS_DIAM_GY_AVP_CODE_RE_AUTH_REQUEST_TYPE (285)
#define OGS_DIAM_GY_AVP_CODE_CC_INPUT_OCTETS (412)
#define OGS_DIAM_GY_AVP_CODE_CC_OUTPUT_OCTETS (414)
#define OGS_DIAM_GY_AVP_CODE_CC_REQUEST_NUMBER (415)
#define OGS_DIAM_GY_AVP_CODE_CC_REQUEST_TYPE (416)
#define OGS_DIAM_GY_AVP_CODE_CC_TIME (420)
#define OGS_DIAM_GY_AVP_CODE_CC_TOTAL_OCTETS (421)
#define OGS_DIAM_GY_AVP_CODE_GRANTED_SERVICE_UNIT (431)
#define OGS_DIAM_GY_AVP_CODE_VALIDITY_TIME (448)
#define OGS_DIAM_GY_AVP_CODE_MULTIPLE_SERVICES_CREDIT_CONTROL (456)
#define OGS_DIAM_GY_AVP_CODE_SUPPORTED_FEATURES (628)
#define OGS_DIAM_GY_AVP_CODE_TIME_QUOTA_THRESHOLD (868)
#define OGS_DIAM_GY_AVP_CODE_VOLUME_QUOTA_THRESHOLD (869)
#define OGS_DIAM_GY_AVP_CODE_CHARGING_RULE_BASE_NAME (1004)
#define OGS_DIAM_GY_AVP_CODE_FLOW_INFORMATION (1058)
#define OGS_DIAM_GY_AVP_CODE_QOS_INFORMATION (1016)
extern struct dict_object *ogs_diam_gy_application;
extern struct dict_object *ogs_diam_gy_cmd_ccr;
extern struct dict_object *ogs_diam_gy_cmd_cca;
extern struct dict_object *ogs_diam_gy_cmd_rar;
extern struct dict_object *ogs_diam_gy_cmd_raa;
extern struct dict_object *ogs_diam_gy_cc_request_type;
extern struct dict_object *ogs_diam_gy_cc_request_number;
extern struct dict_object *ogs_diam_gy_requested_action;
#define OGS_DIAM_GY_REQUESTED_ACTION_DIRECT_DEBITING 0
#define OGS_DIAM_GY_REQUESTED_ACTION_REFUND_ACCOUNT 1
#define OGS_DIAM_GY_REQUESTED_ACTION_CHECK_BALANCE 2
#define OGS_DIAM_GY_REQUESTED_ACTION_PRICE_ENQUIRY 3
extern struct dict_object *ogs_diam_gy_aoc_request_type;
#define OGS_DIAM_GY_AoC_NOT_REQUESTED 0
#define OGS_DIAM_GY_AoC_FULL 1
#define OGS_DIAM_GY_AoC_COST_ONLY 2
#define OGS_DIAM_GY_AoC_TARIFF_ONLY 3
extern struct dict_object *ogs_diam_gy_multiple_services_ind;
#define OGS_DIAM_GY_MULTIPLE_SERVICES_NOT_SUPPORTED 0
#define OGS_DIAM_GY_MULTIPLE_SERVICES_SUPPORTED 1
extern struct dict_object *ogs_diam_gy_multiple_services_cc;
extern struct dict_object *ogs_diam_gy_requested_service_unit;
extern struct dict_object *ogs_diam_gy_used_service_unit;
extern struct dict_object *ogs_diam_gy_cc_time;
extern struct dict_object *ogs_diam_gy_cc_total_octets;
extern struct dict_object *ogs_diam_gy_cc_input_octets;
extern struct dict_object *ogs_diam_gy_cc_output_octets;
extern struct dict_object *ogs_diam_gy_cc_service_specific_units;
extern struct dict_object *ogs_diam_gy_reporting_reason;
#define OGS_DIAM_GY_REPORTING_REASON_THRESHOLD 0
#define OGS_DIAM_GY_REPORTING_REASON_QHT 1
#define OGS_DIAM_GY_REPORTING_REASON_FINAL 2
#define OGS_DIAM_GY_REPORTING_REASON_QUOTA_EXHAUSTED 3
#define OGS_DIAM_GY_REPORTING_REASON_VALIDITY_TIME 4
#define OGS_DIAM_GY_REPORTING_REASON_OTHER_QUOTA_TYPE 5
#define OGS_DIAM_GY_REPORTING_REASON_RATING_CONDITION_CHANGE 6
#define OGS_DIAM_GY_REPORTING_REASON_FORCED_REAUTHORISATION 7
#define OGS_DIAM_GY_REPORTING_REASON_POOL_EXHAUSTED 8
#define OGS_DIAM_GY_REPORTING_REASON_UNUSED_QUOTA_TIMER 9
extern struct dict_object *ogs_diam_gy_service_id;
extern struct dict_object *ogs_diam_gy_service_information;
extern struct dict_object *ogs_diam_gy_ps_information;
extern struct dict_object *ogs_diam_gy_3gpp_charging_id;
extern struct dict_object *ogs_diam_gy_3gpp_pdp_type;
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4 0
#define OGS_DIAM_GY_3GPP_PDP_TYPE_PPP 1
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv6 2
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4v6 3
#define OGS_DIAM_GY_3GPP_PDP_TYPE_NON_IP 4
#define OGS_DIAM_GY_3GPP_PDP_TYPE_UNSTRUCTURED 5
#define OGS_DIAM_GY_3GPP_PDP_TYPE_ETHERNET 6
extern struct dict_object *ogs_diam_gy_pdp_address;
extern struct dict_object *ogs_diam_gy_sgsn_address;
extern struct dict_object *ogs_diam_gy_ggsn_address;
extern struct dict_object *ogs_diam_gy_3gpp_nsapi;
extern struct dict_object *ogs_diam_gy_3gpp_selection_mode;
extern struct dict_object *ogs_diam_gy_3gpp_charging_characteristics;
extern struct dict_object *ogs_diam_gy_user_equipment_info;
extern struct dict_object *ogs_diam_gy_user_equipment_info_type;
extern struct dict_object *ogs_diam_gy_user_equipment_info_value;
extern struct dict_object *ogs_diam_gy_feature_list_id;
extern struct dict_object *ogs_diam_gy_feature_list;
extern struct dict_object *ogs_diam_gy_qos_information;
extern struct dict_object *ogs_diam_gy_qos_class_identifier;
extern struct dict_object *ogs_diam_gy_max_requested_bandwidth_ul;
extern struct dict_object *ogs_diam_gy_max_requested_bandwidth_dl;
extern struct dict_object *ogs_diam_gy_guaranteed_bitrate_ul;
extern struct dict_object *ogs_diam_gy_guaranteed_bitrate_dl;
extern struct dict_object *ogs_diam_gy_allocation_retention_priority;
extern struct dict_object *ogs_diam_gy_priority_level;
extern struct dict_object *ogs_diam_gy_pre_emption_capability;
extern struct dict_object *ogs_diam_gy_pre_emption_vulnerability;
extern struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_ul;
extern struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_dl;
extern struct dict_object *ogs_diam_gy_3gpp_rat_type;
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_CGI 0
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_SAI 1
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_RAI 2
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI 128
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI 129
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI 130
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ENODEB_ID 131
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ENODEB_ID 132
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_EXT_ENODEB_ID 133
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_EXT_ENODEB_ID 134
extern struct dict_object *ogs_diam_gy_3gpp_user_location_info;
extern struct dict_object *ogs_diam_gy_called_station_id;
extern struct dict_object *ogs_diam_gy_3gpp_ms_timezone;
extern struct dict_object *ogs_diam_gy_charging_rule_base_name;;
extern struct dict_object *ogs_diam_gy_flows;
extern struct dict_object *ogs_diam_gy_3gpp_sgsn_mcc_mnc;
typedef struct ogs_diam_gy_service_unit_s {
bool cc_time_present;
uint32_t cc_time;
bool cc_total_octets_present;
uint64_t cc_total_octets;
bool cc_input_octets_present;
uint64_t cc_input_octets;
bool cc_output_octets_present;
uint64_t cc_output_octets;
} ogs_diam_gy_service_unit_t;
typedef struct ogs_diam_gy_message_s {
#define OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL 272
#define OGS_DIAM_GY_CMD_RE_AUTH 258
uint16_t cmd_code;
/* Experimental-Result-Codes */
#define OGS_DIAM_GY_DIAMETER_ERROR_LATE_OVERLAPPING_REQUEST 5453
#define OGS_DIAM_GY_DIAMETER_ERROR_TIMED_OUT_REQUEST 5454
#define OGS_DIAM_GY_DIAMETER_ERROR_INITIAL_PARAMETERS 5140
#define OGS_DIAM_GY_DIAMETER_ERROR_TRIGGER_EVENT 5141
#define OGS_DIAM_GY_DIAMETER_PCC_RULE_EVENT 5142
#define OGS_DIAM_GY_DIAMETER_ERROR_BEARER_NOT_AUTHORIZED 5143
#define OGS_DIAM_GY_DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED 5144
#define OGS_DIAM_GY_DIAMETER_ERROR_CONFLICTING_REQUEST 5147
#define OGS_DIAM_GY_DIAMETER_ADC_RULE_EVENT 5148
#define OGS_DIAM_GY_DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED 5149
uint32_t result_code;
uint32_t *err;
uint32_t *exp_err;
#define OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST 1
#define OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST 2
#define OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST 3
#define OGS_DIAM_GY_CC_REQUEST_TYPE_EVENT_REQUEST 4
uint32_t cc_request_type;
union {
struct {
uint32_t validity_time;
uint32_t time_threshold;
uint32_t volume_threshold;
ogs_diam_gy_service_unit_t granted;
} cca;
};
} ogs_diam_gy_message_t;
int ogs_diam_gy_init(void);
#ifdef __cplusplus
}
#endif
#endif /* OGS_DIAM_GY_MESSAGE_H */

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef OGS_DIAMETER_GY_H
#define OGS_DIAMETER_GY_H
#include "ogs-diameter-common.h"
#define OGS_DIAMETER_INSIDE
#include "diameter/gy/message.h"
#undef OGS_DIAMETER_INSIDE
#ifdef __cplusplus
extern "C" {
#endif
/* Nothing */
#ifdef __cplusplus
}
#endif
#endif /* OGS_DIAMETER_GY_H */

View File

@@ -17,6 +17,7 @@
subdir('common')
subdir('gx')
subdir('gy')
subdir('rx')
subdir('s6a')
subdir('cx')

View File

@@ -56,7 +56,6 @@ struct dict_object *ogs_diam_rx_framed_ip_address = NULL;
struct dict_object *ogs_diam_rx_framed_ipv6_prefix = NULL;
struct dict_object *ogs_diam_rx_ip_can_type = NULL;
struct dict_object *ogs_diam_rx_abort_cause = NULL;
struct dict_object *ogs_diam_rx_termination_cause = NULL;
extern int ogs_dict_rx_entry(char *conffile);
@@ -100,7 +99,6 @@ int ogs_diam_rx_init(void)
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Framed-IPv6-Prefix", &ogs_diam_rx_framed_ipv6_prefix);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IP-CAN-Type", &ogs_diam_rx_ip_can_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Abort-Cause", &ogs_diam_rx_abort_cause);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Termination-Cause", &ogs_diam_rx_termination_cause);
return 0;
}

View File

@@ -121,15 +121,6 @@ extern struct dict_object *ogs_diam_rx_ip_can_type;
#define OGS_DIAM_RX_ABORT_CAUSE_PS_TO_CS_HANDOVER 3
#define OGS_DIAM_RX_ABORT_CAUSE_SPONSORED_DATA_CONNECTIVITY_DISALLOWED 4
extern struct dict_object *ogs_diam_rx_abort_cause;
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_LOGOUT 1
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_SERVICE_NOT_PROVIDED 2
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_BAD_ANSWER 3
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_DIAMETER_ADMINISTRATIVE 4
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_LINK_BROKEN 5
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_AUTH_EXPIRED 6
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_USER_MOVED 7
#define OGS_DIAM_RX_TERMINATION_CAUSE_DIAMETER_SESSION_TIMEOUT 8
extern struct dict_object *ogs_diam_rx_termination_cause;
typedef struct ogs_diam_rx_message_s {
#define OGS_DIAM_RX_CMD_CODE_AA 265

View File

@@ -34,6 +34,14 @@ extern struct dict_object *ogs_diam_s6b_application;
extern struct dict_object *ogs_diam_s6b_mip6_feature_vector;
typedef struct ogs_diam_s6b_message_s {
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 1
uint16_t cmd_code;
uint32_t result_code;
uint32_t *err;
uint32_t *exp_err;
} ogs_diam_s6b_message_t;
int ogs_diam_s6b_init(void);
#ifdef __cplusplus

View File

@@ -105,6 +105,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&gtpc_array) ==
YAML_MAPPING_NODE) {
memcpy(&gtpc_iter, &gtpc_array,
@@ -161,6 +164,15 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (v) port = atoi(v);
} else if (!strcmp(gtpc_key, "dev")) {
dev = ogs_yaml_iter_value(&gtpc_iter);
} else if (!strcmp(gtpc_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&gtpc_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(gtpc_key, "tac")) {
/* Nothing */
} else if (!strcmp(gtpc_key, "e_cell_id")) {
/* Nothing */
} else
ogs_warn("unknown key `%s`", gtpc_key);
}
@@ -175,10 +187,12 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.gtpc_list, AF_INET, addr);
&self.gtpc_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.gtpc_list6, AF_INET6, addr);
&self.gtpc_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@@ -188,7 +202,8 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
NULL : &self.gtpc_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.gtpc_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@@ -202,7 +217,7 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
NULL : &self.gtpc_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.gtpc_list6,
NULL, self.gtpc_port);
NULL, self.gtpc_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(local_key, "gtpu")) {
@@ -229,6 +244,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
const char *network_instance = NULL;
const char *source_interface = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&gtpu_array) ==
YAML_MAPPING_NODE) {
memcpy(&gtpu_iter, &gtpu_array,
@@ -317,6 +335,11 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (v) port = atoi(v);
} else if (!strcmp(gtpu_key, "dev")) {
dev = ogs_yaml_iter_value(&gtpu_iter);
} else if (!strcmp(gtpu_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&gtpu_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(gtpu_key,
"teid_range_indication")) {
teid_range_indication =
@@ -348,9 +371,13 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(&list, AF_INET, addr);
ogs_socknode_add(
&list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(&list6, AF_INET6, addr);
ogs_socknode_add(
&list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@@ -358,7 +385,8 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@@ -452,9 +480,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
ogs_list_init(&list6);
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
NULL, self.gtpu_port);
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
NULL, self.gtpu_port, NULL);
ogs_assert(rv == OGS_OK);
/*
@@ -524,7 +552,7 @@ void ogs_gtp_node_free(ogs_gtp_node_t *node)
}
ogs_gtp_node_t *ogs_gtp_node_add_by_f_teid(
ogs_list_t *list, ogs_gtp_f_teid_t *f_teid, uint16_t port)
ogs_list_t *list, ogs_gtp2_f_teid_t *f_teid, uint16_t port)
{
int rv;
ogs_gtp_node_t *node = NULL;
@@ -534,7 +562,7 @@ ogs_gtp_node_t *ogs_gtp_node_add_by_f_teid(
ogs_assert(f_teid);
ogs_assert(port);
rv = ogs_gtp_f_teid_to_sockaddr(f_teid, port, &addr);
rv = ogs_gtp2_f_teid_to_sockaddr(f_teid, port, &addr);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
rv = ogs_filter_ip_version(
@@ -544,13 +572,15 @@ ogs_gtp_node_t *ogs_gtp_node_add_by_f_teid(
ogs_app()->parameter.prefer_ipv4);
ogs_assert(addr);
#if 0 /* deprecated */
rv = ogs_socknode_fill_scope_id_in_local(addr);
ogs_assert(rv == OGS_OK);
#endif
node = ogs_gtp_node_new(addr);
ogs_assert(node);
rv = ogs_gtp_f_teid_to_ip(f_teid, &node->ip);
rv = ogs_gtp2_f_teid_to_ip(f_teid, &node->ip);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
ogs_list_add(list, node);
@@ -589,7 +619,7 @@ void ogs_gtp_node_remove(ogs_list_t *list, ogs_gtp_node_t *node)
void ogs_gtp_node_remove_all(ogs_list_t *list)
{
ogs_gtp_node_t *node = NULL, *next_node = NULL;
ogs_list_for_each_safe(list, next_node, node)
ogs_gtp_node_remove(list, node);
}
@@ -611,7 +641,7 @@ ogs_gtp_node_t *ogs_gtp_node_find_by_addr(
}
ogs_gtp_node_t *ogs_gtp_node_find_by_f_teid(
ogs_list_t *list, ogs_gtp_f_teid_t *f_teid)
ogs_list_t *list, ogs_gtp2_f_teid_t *f_teid)
{
int rv;
ogs_gtp_node_t *node = NULL;
@@ -620,7 +650,7 @@ ogs_gtp_node_t *ogs_gtp_node_find_by_f_teid(
ogs_assert(list);
ogs_assert(f_teid);
rv = ogs_gtp_f_teid_to_ip(f_teid, &ip);
rv = ogs_gtp2_f_teid_to_ip(f_teid, &ip);
ogs_assert(rv == OGS_OK);
ogs_list_for_each(list, node) {
@@ -652,8 +682,10 @@ ogs_gtp_node_t *ogs_gtp_node_add_by_ip(
ogs_app()->parameter.prefer_ipv4);
ogs_expect_or_return_val(addr, NULL);
#if 0 /* deprecated */
rv = ogs_socknode_fill_scope_id_in_local(addr);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
#endif
node = ogs_gtp_node_new(addr);
ogs_expect_or_return_val(node, NULL);
@@ -673,7 +705,7 @@ ogs_gtp_node_t *ogs_gtp_node_find_by_ip(ogs_list_t *list, ogs_ip_t *ip)
ogs_assert(ip);
ogs_list_for_each(list, node) {
if (node->ip.len == ip->len && memcmp(&node->ip, ip, ip->len) == 0)
if (memcmp(&node->ip, ip, sizeof(*ip)) == 0)
break;
}

Some files were not shown because too many files have changed in this diff Show More