Expand description
GTP-U for the user plane of 5G and 4G, per 3GPP TS 29.281, with the PDU Session Container of TS 38.415: a codec, an endpoint for the tunnels of a base station, a UPF to test against, Linux TUN devices and an eBPF fast path.
use oxirush_gtp_u::{DownlinkPduSessionInformation, Packet, PduSessionContainer};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// An uplink G-PDU of QoS flow 9, as a gNB sends it on N3: the header,
// the PDU Session Container, then the IP packet
let uplink = Packet::uplink(0x1234_5678, 9, b"an IP packet".as_slice());
let bytes = uplink.encode()?;
println!("{:02x?}", &bytes[..16]);
// Decode it. The payload stays in the datagram
let decoded = Packet::decode_borrowed(&bytes)?;
println!("TEID {:#x}, QFI {:?}", decoded.teid, decoded.qfi());
println!("{:?}", String::from_utf8_lossy(decoded.payload));
// A downlink G-PDU whose container has more than a QFI
let mut information = DownlinkPduSessionInformation::new(9);
information.rqi = true;
let downlink = Packet::g_pdu(0x9abc_def0, b"an IP packet".as_slice())
.with_pdu_session_container(PduSessionContainer::Downlink(information));
let decoded = Packet::decode(&downlink.encode()?)?;
if let Some(PduSessionContainer::Downlink(information)) = decoded.pdu_session_container() {
println!("QFI {}, RQI {}", information.qfi, information.rqi);
}
Ok(())
}[34, ff, 00, 14, 12, 34, 56, 78, 00, 00, 00, 85, 01, 10, 09, 00]
TEID 0x12345678, QFI Some(9)
"an IP packet"
QFI 9, RQI true§Tasks
The README has a program for each, with what it prints.
| Task | Items |
|---|---|
| Encode and decode a G-PDU | Packet, Packet::uplink, Packet::decode_borrowed, PduSessionContainer |
| Carry a PDU session between a gNB and the test UPF | Endpoint, Endpoint::install, Endpoint::send, upf_sim::UpfSimulator, upf_sim::Session, ipv4_udp |
| Supervise the path to a peer | Endpoint::echo, Endpoint::supervise, Endpoint::path_state, Endpoint::path_events, PathEvent |
| Answer a peer: Echo and Error Indication | Packet::echo_request, InformationElement |
| Read and write extension headers | ExtensionHeader, ExtensionHeaders, ExtensionHeaderType |
| The headers of a handover | ExtensionHeader::PdcpPduNumber, Packet::end_marker |
| Give a tunnel a TUN, on Linux | tun::TunConfig, tun::Routing, Endpoint::attach_tun |
| Carry the tunnel in the kernel, on Linux | ebpf::FastPath, Endpoint::set_fast_path |
It is made for simulators and test tools. It has no control plane: tunnels are set up by calls, with the identifiers and addresses that NGAP, S1AP or PFCP would negotiate.
§Where things are
| Part | Feature | Needs |
|---|---|---|
The codec (Packet, ExtensionHeader, InformationElement) and the IPv4 helpers | none | no dependency |
Endpoint, upf_sim | endpoint, the default | a Tokio runtime |
tun, and attach_tun of Endpoint and UpfSimulator | tun | Linux, CAP_NET_ADMIN |
ebpf | ebpf | Linux 6.6, CAP_BPF and CAP_NET_ADMIN |
Serialize and Deserialize for RemoteTunnel | serde | |
The oxirush-upf-sim program | cli |
ebpf brings tun, and tun, serde and cli bring endpoint. The
tun and ebpf modules exist on Linux only; elsewhere their features build
and add nothing to endpoint. So does ebpf where the programs cannot run: on an
architecture that their loader, aya, does not build for, such as 32-bit
x86, and on a big-endian one, such as s390x, as their object is for
little-endian eBPF. It runs on 64-bit x86, ARM, AArch64, RISC-V 64,
LoongArch 64, and little-endian MIPS and PowerPC 64. The reference of each
part is with it: Endpoint, and the modules upf_sim, tun and ebpf.
§Codec
Packet has every header field of TS 29.281 §5.1, the chain of extension
headers and the payload. There are constructors for G-PDU, Echo Request and
Response, Error Indication, Supported Extension Headers Notification and End
Marker; Packet::new and InformationElement::encode_all build any
other message.
Every extension header of TS 29.281 V19.2.0 §5.2.2 is a variant of
ExtensionHeader. The PDU Session Container has the downlink and uplink
PDU Session Information of TS 38.415 V19.1.0 §5.5.2, with the QoS
monitoring, sequence number, delay and congestion fields, the downlink
Burst Size and Time To Next Burst, and the uplink Available Bitrates. The
PDCP PDU Number, the long one and the Service Class Indicator are their
numbers. The PDU Set Information Container has the downlink PDU Set
Information of TS 38.415 §6.5.2. The RAN Container, the Xw RAN Container
and the NR RAN Container are the octets of a frame of TS 36.425, TS 36.465
or TS 38.425, which the crate does not read.
The numbers that say what a message, an extension header, an information
element or a cause is are types that know the names of the specification:
MessageType, ExtensionHeaderType, InformationElementType and
Cause. Debug prints these names, a TEID in hexadecimal, and a payload
or a value that is kept as received as its length and all its octets in
hexadecimal.
Decoding follows the receiver rules of §5.1: the flags decide which optional fields are read and the spare bit is ignored. Extension headers, TLV information elements and uplink New IEs that have no type of their own are kept as received. A TV information element imported from TS 29.060 is kept when its fixed length is known; an unknown TV type is an error. What decodes encodes to a message that decodes to the same value.
Packet::extension_headers is an ExtensionHeaders, the chain in its
order on the wire: a slice to read and to change, push to add a header,
and From a Vec and back for the rest. It keeps its first header in the
list itself. A message without extension header, or with one, such as the
PDU Session Container of a G-PDU on N3, is decoded and made without an
allocation; a second header allocates the list, and a header or a PDU type
that is kept as received allocates its octets.
Packet<P> takes any payload that is AsRef<[u8]>, Vec<u8> by default.
Packet::decode_borrowed returns a Packet<&[u8]> whose payload stays
in the datagram, and into_owned copies it. encoded_len gives the wire
length without encoding. encode_into appends to a Vec<u8> and leaves it
as it was on an error. The codec’s Error names the Part of the
message that is wrong and has the numbers that disagree. It converts into
a std::io::Error, for ? next to an endpoint’s calls.
ipv4_udp and ipv4_icmp_echo_request build inner packets, and
parse_ipv4_udp and parse_ipv4_icmp_echo read them, to exercise a
tunnel without a TUN. They are IPv4 only; any payload, IPv6 included, is
carried as it is.
§What it covers
| What | API | Specification |
|---|---|---|
| Messages | Packet: every header field, the chain of extension headers, the information elements, and constructors for G-PDU, Echo Request and Response, Error Indication, Supported Extension Headers Notification and End Marker | TS 29.281 §5, §7 and §8 |
| Extension headers | ExtensionHeader: the UDP Port, the PDCP PDU Number and the long one, the Service Class Indicator, the RAN, Xw RAN and NR RAN containers as octets, and the two below; a header of another type is kept as octets | TS 29.281 §5.2 |
| PDU Session Container | PduSessionContainer: the downlink and the uplink PDU Session Information, with their QoS monitoring, sequence number, delay and congestion fields | TS 38.415 §5.5.2 |
| PDU Set Information Container | PduSetInformationContainer: the downlink PDU Set Information | TS 38.415 §6.5.2 |
| Tunnels of a gNB or an eNB | Endpoint: tunnels by UE and PDU session or E-RAB, the replies that a node owes its peer, Echo Requests and the supervision of a path | TS 29.281 §4.4, §7 and §11, TS 23.007 §20.3 |
| A UPF to test against | upf_sim::UpfSimulator and the oxirush-upf-sim program: sessions, an echo service, an End Marker on a path switch | |
| Linux as the device or as N6 | tun::TunPort, Endpoint::attach_tun, UpfSimulator::attach_tun | |
| The tunnels in the kernel | ebpf::FastPath | |
| Inner packets for tests | ipv4_udp, ipv4_icmp_echo_request and their parsers |
§Limits
| Subject | Limit |
|---|---|
| Control plane | None: no NGAP, S1AP or PFCP. A call gives a tunnel its TEIDs and addresses. |
| Authentication | GTP-U has none: anyone who reaches a socket can send on its tunnels. |
| A UPF for real traffic | The test UPF serves the sessions that calls give it, with an echo service or a TUN. It has no PFCP, QoS or charging. |
| Other GTP | GTP’ and the versions 0 and 2 are refused, as UnsupportedVersion. |
| IPv6 in the helpers, the TUN routing and the fast path | They are IPv4. The codec and the endpoint carry any payload, and an endpoint binds an IPv4 or an IPv6 address. |
| Transport QoS and load balancing | Every G-PDU, through the socket or the fast path, has DSCP 0 and source port 2152. TS 29.281 §4.4.1 asks for the DSCP of the QoS flow’s 5QI, which a call does not give, and §4.4.2.0 for source ports that vary, which one socket cannot have. |
| Portability | tun and ebpf are Linux only, and ebpf adds nothing on 32-bit x86, which aya does not build for, and on big-endian architectures. |
§Terms
| Term | Meaning |
|---|---|
| UE, gNB, eNB | The device (User Equipment), and the base station of 5G and of 4G |
| UPF | User Plane Function: the node of the 5G core network that carries the traffic of the devices |
| N3, S1-U, N6 | The interface between a gNB and a UPF, the one between an eNB and the gateway of a 4G core network, and the one between a UPF and the network that the devices reach |
| Tunnel | The path of one PDU session of 5G, or of one bearer of 4G (an E-RAB), between two GTP-U nodes |
| TEID | Tunnel Endpoint Identifier: the 32 bits in a GTP-U header that name the tunnel to the node that receives the message. Each end chooses the one it receives on |
| G-PDU | The GTP-U message that carries one packet of a device, here an IP packet |
| QFI | QoS Flow Identifier: the 6 bits that name the QoS flow of a packet in a 5G tunnel |
| PDU Session Container | The extension header of a G-PDU that carries the QFI on N3 (TS 38.415) |
| Echo, Error Indication, End Marker | The messages with which GTP-U nodes test a path, refuse a G-PDU of an unknown tunnel and close the old path of a handover |
| TUN | A network interface of Linux whose packets a program reads and writes |
| TCX | The attachment of eBPF programs to the ingress and the egress of an interface, since Linux 6.6 |
§Specifications
- 3GPP TS 29.281: GTPv1-U (header, extension headers, messages, information elements, path management)
- 3GPP TS 38.415: NG-RAN PDU Session User Plane protocol (PDU Session Container, PDU Set Information Container)
- 3GPP TS 29.060: imported TV information elements and receive rules
- 3GPP TS 23.007: the supervision of a path (§20.3)
§Source layout
src/
├── packet.rs owned and borrowed messages (TS 29.281 §5.1, §6, §7)
├── types.rs message, header and element types, and causes, by name
├── extension.rs extension headers and PDU Session Container (TS 38.415)
├── pdu_set.rs PDU Set Information Container (TS 38.415)
├── headers.rs the list of the extension headers of a message
├── ie.rs, error.rs information elements and codec errors
├── ipv4.rs, icmp.rs inner IPv4 UDP and ICMP Echo packets
├── datagram.rs, path.rs shared UDP receive and path management (endpoint)
├── limit.rs the limits of replies and log lines (endpoint)
├── endpoint.rs gNB endpoint and forwarding (endpoint)
├── endpoint/paths.rs Echo Requests, path supervision, peers' notifications (endpoint)
├── endpoint/routes.rs tunnel identity, route indexes and TUNs (endpoint)
├── stats.rs receive/drop counters (endpoint)
├── upf_sim.rs test UPF and forwarding (endpoint)
├── upf_sim/sessions.rs session generations and handover state (endpoint)
├── tun.rs public TUN API (tun)
├── tun/device.rs TUN descriptor and packet I/O (tun)
├── tun/routing.rs routing ownership and cleanup (tun)
├── tun/error.rs contextual I/O errors (tun)
├── netlink.rs rtnetlink operations (tun)
├── ebpf.rs loader of the fast path and its tunnels (ebpf)
├── ebpf/layout.rs map layouts shared with the programs (ebpf)
├── ebpf/programs.rs the TCX programs: uplink, encap, decap
├── ebpf/gtpu.o their object, built by ../ebpf (ebpf)
└── bin/oxirush-upf-sim.rs
ebpf/ what builds programs.rs for eBPF: build.sh and its manifest
examples/ the programs of the README
benches/ the benchmarks, a package of their own§The OxiRush family
- oxirush-utils: the 3GPP identities, and the JSON tree with its paths that the others share.
- oxirush-aper: aligned PER, the runtime of the NGAP and S1AP codecs.
- oxirush-nas: the NAS messages of 5GS and EPS.
- oxirush-security: NAS security, AKA and the derivation of keys.
- oxirush-ngap: NGAP, between a gNB and an AMF.
- oxirush-s1ap: S1AP, between an eNB and an MME.
- oxirush-gtp-u: GTP-U tunnels, with a test UPF.
- oxirush-sctp: SCTP sockets, which carry NGAP and S1AP.
Modules§
- ebpf
Linux and ebpf - The eBPF fast path of an
Endpoint’s tunnels. - tun
Linux and tun - Linux TUN devices and their routing, for UE and UPF sessions.
- upf_sim
endpoint - A test UPF: an N3 peer whose sessions are provisioned directly, without
PFCP. Its N6 is a built-in echo service, or a Linux TUN per session.
UpfSimulatoris an N3 peer whose sessions are set withset_session. Uplink packets go to the echo service, which reflects IPv4 UDP and answers ICMP Echo Requests, or to the TUN thatattach_tungives the session.set_echo_serviceturns the echo service off, for a program that answers the UE itself.send_downlinksends a packet to the UE. The receiver ofbindobserves the uplink G-PDUs.
Structs§
- Cause
- The value of a Cause information element (TS 29.060 table 38). The names here are those of the causes that a GTP-U node can give or get; the others of the table are about PDP contexts.
- Downlink
PduSession Information - DL PDU SESSION INFORMATION (TS 38.415 §5.5.2.1). Time stamps are 64-bit NTP timestamps (RFC 5905 §6).
- Downlink
PduSet Information - DL PDU SET INFORMATION (TS 38.415 §6.5.2.1).
- Endpoint
endpoint - One UDP socket carrying a gNB’s N3 tunnels, each identified by a RAN UE identifier (such as the RAN UE NGAP ID) and a PDU session ID, or an eNB’s S1-U tunnels, identified by the eNB UE S1AP ID and E-RAB ID.
- Extension
Header Type - The type of a GTP-U extension header (TS 29.281 figure 5.2.1-3). It is printed in hexadecimal, as the specification writes it in binary.
- Extension
Headers - The extension headers of a message, in their order on the wire (TS 29.281 §5.2).
- Extension
Headers Into Iter - The headers of an
ExtensionHeaders, taken out of it in their order: what itsinto_iterreturns. - Icmp
Echo - A parsed IPv4 ICMP Echo message.
- Information
Element Type - The type of a GTP-U information element (TS 29.281 table 8.1-1). Below 128 an element has a fixed length and no length field (TV); from 128 it has one (TLV).
- Message
Type - The type of a GTP-U message (TS 29.281 §6.1).
- Packet
- A GTP-U message: the header, its extension headers and the payload.
- Path
State endpoint - The state of a path that an endpoint supervises
(
Endpoint::supervise). - Path
Timers endpoint - The timers with which an endpoint sends Echo Requests (TS 29.281 §11, §12) and supervises a path (§7.2.1, TS 23.007 §20.3.1).
- Receive
Stats endpoint - Individually sampled receive counters shared by all clones of an endpoint.
- Received
Packet endpoint - A message for one of the endpoint’s tunnels.
- Remote
Tunnel endpoint - The far end of a tunnel: the peer’s GTP-U address and the TEID it
assigned (an F-TEID).
Debugprints the TEID in hexadecimal. - Unknown
NewIes - New IEs of UL PDU Session Information that this crate does not decode: those announced by New IE Flags 5 and 6 and by extension octets of the New IE Flags (TS 38.415 Annex A).
- Uplink
PduSession Information - UL PDU SESSION INFORMATION (TS 38.415 §5.5.2.2). Time stamps are 64-bit NTP timestamps (RFC 5905 §6).
- Uplink
Time Stamps - The QoS monitoring time stamps of UL PDU Session Information.
Enums§
- Echo
Kind - Whether an ICMP Echo message is a request or a reply.
- Error
- Why a GTP-U message, or an inner IPv4 packet, cannot be decoded or encoded.
- Expected
- What an IPv4 helper expected of a packet that is something else
(
Error::UnexpectedPacket). - Extension
Header - A GTP-U extension header (TS 29.281 §5.2).
- Information
Element - A GTP-U information element (TS 29.281 §8).
- Part
- The part of a message that an
Erroris about. - Path
Event endpoint - What an endpoint learns of its paths, from the receiver of
Endpoint::path_events. - PduSession
Container - The content of a PDU Session Container (TS 38.415 §5.5.2).
- PduSet
Information Container - The content of a PDU Set Information Container (TS 38.415 §6.5.2): what a UPF tells an NG-RAN node about the PDU Set of a downlink packet, such as the frame of a video.
Constants§
- PORT
- The UDP port of GTP-U.
Functions§
- ipv4_
icmp_ echo_ reply - Build the IPv4 ICMP Echo Reply to an Echo Request.
- ipv4_
icmp_ echo_ request - Build an IPv4 ICMP Echo Request.
- ipv4_
udp - Build an IPv4 UDP packet from
sourcetodestination. - parse_
ipv4_ icmp_ echo - Parse an IPv4 ICMP Echo Request or Reply. The IPv4 header and ICMP checksums must be valid.
- parse_
ipv4_ udp - Parse an IPv4 UDP packet into its source, destination and payload. The IPv4 header checksum, and the UDP checksum when not 0, must be valid.