neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-upf/+/29143 )
Change subject: improve manual: PFCP and GTP interfaces
......................................................................
improve manual: PFCP and GTP interfaces
Related: SYS#5599
Change-Id: Iccb3f0f52bd5006bc94d0ca06ac5d3271ea89eb9
---
M doc/manuals/chapters/overview.adoc
A doc/manuals/chapters/running.adoc
2 files changed, 208 insertions(+), 0 deletions(-)
Approvals:
fixeria: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/doc/manuals/chapters/overview.adoc b/doc/manuals/chapters/overview.adoc
index 2b9b547..9cd7751 100644
--- a/doc/manuals/chapters/overview.adoc
+++ b/doc/manuals/chapters/overview.adoc
@@ -22,3 +22,160 @@
- 1000 modifications of tunnel state per second (add/remove/modify),
- 4-8 Gbps throughput,
- 100-125k concurrent GTP tunnels.
+
+A typical network scenario using OsmoUPF is illustrated in the following
+diagram:
+
+.Typical network architecture used with OsmoUPF
+[graphviz]
+----
+digraph G {
+ rankdir = LR;
+
+ UE [label="UE\n(3G phone)"]
+
+ subgraph cluster_hnbgw_mgw_upf {
+ style=dotted
+ HNBGW -> UPF [label="PFCP",constraint=false]
+ UPF [label=OsmoUPF,style=bold]
+ }
+
+ subgraph cluster_hnbgw_mgw_upf2 {
+ style=dotted
+ SGSN -> UPF2 [label="PFCP",constraint=false]
+ UPF2 [label=OsmoUPF,style=bold]
+ }
+
+ subgraph cluster_hnbgw_mgw_upf3 {
+ style=dotted
+ GGSN -> UPF3 [label="PFCP",constraint=false]
+ UPF3 [label=OsmoUPF,style=bold]
+ }
+
+ hNodeB [shape="box",label="hNodeB\n(3G femto cell)"]
+
+ UE -> hNodeB [label="Uu"]
+ hNodeB -> HNBGW [label="Iuh",style=dashed]
+ STP [label="STP\n(SCCP/M3UA)"]
+ HNBGW -> STP -> SGSN [label="IuPS",style=dashed]
+ SGSN -> GGSN [label="GTP-C",style="dashed"]
+ hNodeB -> UPF -> UPF2 -> UPF3 [label="GTP-U"]
+ UPF3 -> internet [label="apn"]
+}
+----
+
+NOTE: at the time of writing this section, the only Osmocom component providing
+a PFCP CPF interface is OsmoHNBGW. PFCP support has not yet made its way into
+OsmoSGSN nor OsmoGGSN.
+
+=== the PFCP interface
+
+PFCP is specified by 3GPP TS 29.244.
+
+OsmoUPF implements a PFCP User Plane Function interface, listening for PFCP
+requests from PFCP Control Plane Function clients, to carry out proxy-relaying
+and encapsulation/decapsulation of GTP tunnels.
+
+OsmoUPF does not support the complete PFCP feature set. It detects exactly two
+use cases that will provide service of actual GTP tunnels:
+
+* GTP tunnel encapsulation/decapsulation:
+ - One Packet Detection Rule (PDR) accepts a GTP tunnel from the Access side
+ with an Outer Header Removal.
+ - This PDR uses a Forwarding Action Rule (FAR) for plain IP towards Core.
+ - Another PDR accepts plain IP on a specific IP address from Core.
+ - The second PDR uses a FAR towards Access with Outer Header Creation for GTP.
+
+* GTP tunnel forwarding:
+ - One Packet Detection Rule (PDR) accepts a GTP tunnel from the Access side
+ with an Outer Header Removal.
+ - This PDR uses a Forwarding Action Rule (FAR) towards Core with an Outer
+ Header Creation for GTP.
+ - A second PDR+FAR pair like above, with Access and Core swapped.
+
+Any set of rules only partially or not at all matching the above PDR and FAR
+rules will not result in any actions on the GTP user plane, but will still
+return a successful outcome in the PFCP messages.
+
+For example, a rule set using an interface other than "Access" or "Core" results
+in a PFCP no-op, returning PFCP responses with successful outcome, but not
+providing any GTP-U service.
+
+This is a direct result of:
+
+- allowing PFCP rule sets to be setup incrementally by several subsequent PFCP
+ messages, and of
+- OsmoUPF using Linux kernel features for the GTP user plane, where there is
+ either a full bidirectional GTP tunnel in place or none at all.
+
+For example, a typical CPF will first establish a PFCP session with the UPF
+before passing on a data service request from Access to Core, because the UPF
+must first choose the GTP TEID that needs to be forwarded towards Core. When the
+Core side has responded with its GTP details, the UPF is updated, to form a
+complete PFCP rule set.
+
+.Typical sequence of establishing a GTP-U tunnel relay
+["mscgen"]
+----
+msc {
+ hscale="1";
+ sgsn[label="SGSN"],sgwc[label="SGW-C"],sgwu[label="SGW-U"],pgwc[label="PGW-C"];
+
+ sgsn << pgwc [label="Access"];
+ sgsn >> pgwc [label="Core"];
+
+ sgsn => sgwc [label="GTP Create Session Request\n\n\n"];
+
+ |||;
+
+ sgwc => sgwu [label="PFCP Session Establishment Request\n\n2x Create PDR\nF-TEID = CHOOSE"];
+
+ |||;
+
+ sgwc <= sgwu [label="PFCP Session Establishment Response\n\n2x Created PDR\nwith chosen F-TEID"];
+
+ |||;
+
+ sgwc => pgwc [label="GTP Create Session Request"];
+ sgwc <= pgwc [label="GTP Create Session Response"];
+
+ |||;
+
+ sgwc => sgwu [label="PFCP Session Modification Request\n\nUpdate FAR\nwith F-TEID from Core"];
+
+ |||;
+
+ sgwc <= sgwu [label="PFCP Session Modification Response\n\n\n"];
+
+ |||;
+
+ sgsn <= sgwc [label="GTP Create Session Response\n\n\n"];
+}
+----
+
+The OsmoUPF logging as well as the VTY interface yield information on whether a
+ruleset results in an actual bidirectional GTP tunnel being set up.
+
+
+=== the GTP interface
+
+OsmoUPF requires the following Linux kernel features to provide the GTP user
+plane functionality:
+
+- the Linux kernel GTP module for encapsulation/decapsulation between GTP and
+ plain IP.
+- the Linux netfilter nftables feature for relaying GTP, i.e. forwarding between
+ two GTP tunnels.
+
+Tunnel relaying with netfilter requires at least Linux kernel 5.17.
+
+To be able to interact with these Linux kernel features, the osmo-upf binary
+needs cap_net_admin privileges, as in:
+
+----
+sudo setcap cap_net_admin+pe /usr/bin/osmo-upf
+----
+
+Without above Linux kernel features, or when no cap_net_admin is available,
+OsmoUPF is only useful for testing PFCP clients: the GTP features may be run in
+mockup mode, so that OsmoUPF serves as a "dry run" PFCP server.
diff --git a/doc/manuals/chapters/running.adoc b/doc/manuals/chapters/running.adoc
new file mode 100644
index 0000000..6a6afd4
--- /dev/null
+++ b/doc/manuals/chapters/running.adoc
@@ -0,0 +1,51 @@
+== Running OsmoUPF
+
+The OsmoUPF executable (`osmo-upf`) offers the following command-line
+arguments:
+
+=== SYNOPSIS
+
+*osmo-upf* [-h|-V] [-D] [-c 'CONFIGFILE']
+
+=== OPTIONS
+
+*-h, --help*::
+ Print a short help message about the supported options
+*-V, --version*::
+ Print the compile-time version number of the OsmoHNBGW program
+*-D, --daemonize*::
+ Fork the process as a daemon into background.
+*-c, --config-file 'CONFIGFILE'*::
+ Specify the file and path name of the configuration file to be
+ used. If none is specified, use `osmo-upf.cfg` in the current
+ working directory.
+
+=== Multiple instances
+
+Running multiple instances of `osmo-upf` on the same computer is possible if
+all interfaces (VTY, CTRL, PFCP) are separated using the appropriate
+configuration options. The IP based interfaces are binding to local host by
+default. In order to separate the processes, the user has to bind those
+services to different ports, or different specific IP addresses.
+
+The VTY and the Control interface can be bound to IP addresses from the loopback
+address range, for example:
+
+----
+line vty
+ bind 127.0.0.2
+ctrl
+ bind 127.0.0.2
+----
+
+The PFCP port is specified to be fixed as port 8805. Hence, each osmo-upf
+process needs to run on a distinct local interface:
+
+----
+pfcp
+ local-addr 10.9.0.2
+----
+
+For GTP encapsulation/decapsulation and GTP tunnel relaying, osmo-upf depends on
+the IP addresses configured at the Linux kernel GTP module, and the IP addresses
+negotiated within PFCP by the control plane function.
--
To view, visit https://gerrit.osmocom.org/c/osmo-upf/+/29143
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: Iccb3f0f52bd5006bc94d0ca06ac5d3271ea89eb9
Gerrit-Change-Number: 29143
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-MessageType: merged
neels has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-pfcp/+/29042 )
Change subject: gtlv: fix repeated IEIs to several struct members
......................................................................
gtlv: fix repeated IEIs to several struct members
Coverity Scan has brought my attention to a problem with decoding
repeated IEIs, where there are multiple struct members in the decoded
struct that these are decoded to.
Before this patch, gtlv aborts with an error as soon as the first struct
member for a given tag is full, not parsing following IEIs into
subsequent struct members.
After this patch, gtlv continues to look whether subsequent entries in
the message coding also decode the same tag, but to a different struct
member.
First commit without changing the gtlv regression test, to show that all
current tests still succeed. The test for this particular issue follow
in I994d0fb1f1435d2c27a8630a43fe106652ac6e41
Related: CID#275415
Related: SYS#5599
Change-Id: Ie37585178ff27306d425b75d8e407b71f92f1cdc
---
M src/libosmo-gtlv/gtlv_dec_enc.c
1 file changed, 70 insertions(+), 20 deletions(-)
diff --git a/src/libosmo-gtlv/gtlv_dec_enc.c b/src/libosmo-gtlv/gtlv_dec_enc.c
index 58c0405..385ebfa 100644
--- a/src/libosmo-gtlv/gtlv_dec_enc.c
+++ b/src/libosmo-gtlv/gtlv_dec_enc.c
@@ -127,16 +127,19 @@
* that can store them are filled up. */
ie_max_allowed_count = 0;
+ /* Unordered: for every tag, look for matching IE definitions from the start. */
+ iec = ie_coding;
+ /* There may be multiple subsequent occurences of the same tag, to be decoded into multiple members of
+ * the decoded struct. Iterate until encountering a still "free slot" for decoding. */
do {
/* Find the IE coding for this tag */
- for (iec = ie_coding;
- !osmo_gtlv_coding_end(iec) && osmo_gtlv_tag_inst_cmp(&iec->ti, >lv->ti);
+ for (; !osmo_gtlv_coding_end(iec) && osmo_gtlv_tag_inst_cmp(&iec->ti, >lv->ti);
iec++);
/* No such IE coding found. */
if (osmo_gtlv_coding_end(iec))
break;
- /* Keep track how often this tag can occur */
+ /* Keep track how often this tag can occur in total */
ie_max_allowed_count += iec->has_count ? iec->count_max : 1;
/* Was this iec instance already decoded? Then skip to the next one, if any. */
@@ -145,23 +148,35 @@
multi_count_p = iec->has_count ?
membof(obj, obj_maxlen, iec->count_ofs) : NULL;
if ((presence_flag_p && *presence_flag_p)
- || (multi_count_p && *multi_count_p >= iec->count_max))
+ || (multi_count_p && *multi_count_p >= iec->count_max)) {
+ iec++;
continue;
+ }
+
/* For IEs with a presence flag or a multi count, the decoded struct provides the information
* whether the IE has already been decoded. Do the same for mandatory IEs, using local state in
* seen_ie_coding_entries[]. */
- CHECK_SEEN(iec);
- if (*seen_p)
- continue;
- } while (0);
+ if (!presence_flag_p && !multi_count_p) {
+ CHECK_SEEN(iec);
+ if (*seen_p) {
+ iec++;
+ continue;
+ }
+ }
+
+ /* Found an IE coding that has not yet been decoded / still has unused struct members to decode
+ * to. */
+ break;
+ } while (1);
+
if (osmo_gtlv_coding_end(iec)) {
if (ie_max_allowed_count) {
- /* There have been IE definitions for this IEI, but all slots to decode it are already
- * filled. */
+ /* This tag exists in the protocol definitions, but we've run out of struct members to
+ * decode the tag to. */
RETURN_ERROR(-ENOTSUP, gtlv->ti, "Only %u instances of this IE are supported per message",
ie_max_allowed_count);
}
- /* No such IE defined in ie_coding, just skip the TLV. */
+ /* This is an unknown tag, no such IEI defined in ie_coding, just skip the TLV. */
continue;
}
@@ -264,14 +279,22 @@
osmo_gtlv_load_start(gtlv);
+ /* Ordered: traverse the ie_coding exactly once, expecting tags to be decoded to appear in the same order. */
for (; !osmo_gtlv_coding_end(ie_coding); ie_coding++) {
int rc;
- bool *presence_flag = ie_coding->has_presence_flag ?
- membof(obj, obj_maxlen, ie_coding->presence_flag_ofs) : NULL;
- unsigned int *multi_count = ie_coding->has_count ?
- membof(obj, obj_maxlen, ie_coding->count_ofs) : NULL;
+ bool *presence_flag;
+ unsigned int *multi_count;
struct osmo_gtlv_tag_inst peek_ti;
+#define UPDATE_STATE_FROM_IE_CODING() do { \
+ presence_flag = ie_coding->has_presence_flag ? \
+ membof(obj, obj_maxlen, ie_coding->presence_flag_ofs) : NULL; \
+ multi_count = ie_coding->has_count ? \
+ membof(obj, obj_maxlen, ie_coding->count_ofs) : NULL; \
+ } while (0)
+
+ UPDATE_STATE_FROM_IE_CODING();
+
rc = osmo_gtlv_load_next_by_tag_inst(gtlv, &ie_coding->ti);
switch (rc) {
case 0:
@@ -289,12 +312,39 @@
for (;;) {
/* If this is a repeated IE, decode into the correct array index memb[idx],
* next idx == (*multi_count) */
- unsigned int memb_next_array_idx = multi_count ? *multi_count : 0;
- unsigned int memb_ofs = ie_coding->memb_ofs + memb_next_array_idx * ie_coding->memb_array_pitch;
+ unsigned int memb_next_array_idx;
+ unsigned int memb_ofs;
- if (multi_count && memb_next_array_idx >= ie_coding->count_max)
- RETURN_ERROR(-ENOTSUP, ie_coding->ti, "Only %u instances of this IE are supported per message",
- ie_coding->count_max);
+#define UPDATE_MEMB_IDX() do { \
+ memb_next_array_idx = multi_count ? *multi_count : 0; \
+ memb_ofs = ie_coding->memb_ofs + memb_next_array_idx * ie_coding->memb_array_pitch; \
+ } while (0)
+
+ UPDATE_MEMB_IDX();
+
+ if (multi_count && memb_next_array_idx >= ie_coding->count_max) {
+ /* This repeated IE is full. But the protocol may define this same IEI to follow again,
+ * with a different target struct member. See if this IEI appears again. */
+ const struct osmo_gtlv_coding *iec = ie_coding;
+ bool iei_appears_again = false;
+ for (iec = ie_coding + 1; !osmo_gtlv_coding_end(iec); iec++) {
+ if (osmo_gtlv_tag_inst_cmp(>lv->ti, &iec->ti) == 0) {
+ iei_appears_again = true;
+ break;
+ }
+ }
+
+ if (!iei_appears_again)
+ RETURN_ERROR(-ENOTSUP, ie_coding->ti, "Only %u instances of this IE are supported per message",
+ ie_coding->count_max);
+
+ /* IEI does appear again. Skip forward to this ie_coding, and use that to decode the
+ * current TLV (do not call osmo_gtlv_load_next_by_tag_inst() again, or we'd skip the
+ * TLV in the message being decoded). */
+ ie_coding = iec;
+ UPDATE_STATE_FROM_IE_CODING();
+ UPDATE_MEMB_IDX();
+ }
/* Decode IE value part */
if (ie_coding->nested_ies) {
null--
To view, visit https://gerrit.osmocom.org/c/libosmo-pfcp/+/29042
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-pfcp
Gerrit-Branch: master
Gerrit-Change-Id: Ie37585178ff27306d425b75d8e407b71f92f1cdc
Gerrit-Change-Number: 29042
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-CC: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged
Attention is currently required from: laforge.
fixeria has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/29207 )
Change subject: rlcmac: make logging category configurable
......................................................................
Patch Set 1:
(1 comment)
File src/rlcmac/gprs_rlcmac.c:
https://gerrit.osmocom.org/c/libosmo-gprs/+/29207/comment/a64ec15c_ffcd0e9e
PS1, Line 38: e
> are we sure that this is not globally exported by the library? If you introduce symbols with such ge […]
Yes, this is not a problem. Only symbols prefixed with 'osmo_' are exposed. See 'src/rlcmac/Makefile.am', where we have: -export-symbols-regex '^osmo_'.
--
To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/29207
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: Icfef6de126304da81120f1d7b212992ead3409aa
Gerrit-Change-Number: 29207
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-CC: laforge <laforge(a)osmocom.org>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Comment-Date: Wed, 24 Aug 2022 15:44:47 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: comment