Skip to main content

Crate oxirush_gtp_u

Crate oxirush_gtp_u 

Source
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.

TaskItems
Encode and decode a G-PDUPacket, Packet::uplink, Packet::decode_borrowed, PduSessionContainer
Carry a PDU session between a gNB and the test UPFEndpoint, Endpoint::install, Endpoint::send, upf_sim::UpfSimulator, upf_sim::Session, ipv4_udp
Supervise the path to a peerEndpoint::echo, Endpoint::supervise, Endpoint::path_state, Endpoint::path_events, PathEvent
Answer a peer: Echo and Error IndicationPacket::echo_request, InformationElement
Read and write extension headersExtensionHeader, ExtensionHeaders, ExtensionHeaderType
The headers of a handoverExtensionHeader::PdcpPduNumber, Packet::end_marker
Give a tunnel a TUN, on Linuxtun::TunConfig, tun::Routing, Endpoint::attach_tun
Carry the tunnel in the kernel, on Linuxebpf::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

PartFeatureNeeds
The codec (Packet, ExtensionHeader, InformationElement) and the IPv4 helpersnoneno dependency
Endpoint, upf_simendpoint, the defaulta Tokio runtime
tun, and attach_tun of Endpoint and UpfSimulatortunLinux, CAP_NET_ADMIN
ebpfebpfLinux 6.6, CAP_BPF and CAP_NET_ADMIN
Serialize and Deserialize for RemoteTunnelserde
The oxirush-upf-sim programcli

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

WhatAPISpecification
MessagesPacket: 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 MarkerTS 29.281 §5, §7 and §8
Extension headersExtensionHeader: 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 octetsTS 29.281 §5.2
PDU Session ContainerPduSessionContainer: the downlink and the uplink PDU Session Information, with their QoS monitoring, sequence number, delay and congestion fieldsTS 38.415 §5.5.2
PDU Set Information ContainerPduSetInformationContainer: the downlink PDU Set InformationTS 38.415 §6.5.2
Tunnels of a gNB or an eNBEndpoint: tunnels by UE and PDU session or E-RAB, the replies that a node owes its peer, Echo Requests and the supervision of a pathTS 29.281 §4.4, §7 and §11, TS 23.007 §20.3
A UPF to test againstupf_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 N6tun::TunPort, Endpoint::attach_tun, UpfSimulator::attach_tun
The tunnels in the kernelebpf::FastPath
Inner packets for testsipv4_udp, ipv4_icmp_echo_request and their parsers

§Limits

SubjectLimit
Control planeNone: no NGAP, S1AP or PFCP. A call gives a tunnel its TEIDs and addresses.
AuthenticationGTP-U has none: anyone who reaches a socket can send on its tunnels.
A UPF for real trafficThe test UPF serves the sessions that calls give it, with an echo service or a TUN. It has no PFCP, QoS or charging.
Other GTPGTP’ and the versions 0 and 2 are refused, as UnsupportedVersion.
IPv6 in the helpers, the TUN routing and the fast pathThey are IPv4. The codec and the endpoint carry any payload, and an endpoint binds an IPv4 or an IPv6 address.
Transport QoS and load balancingEvery 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.
Portabilitytun 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

TermMeaning
UE, gNB, eNBThe device (User Equipment), and the base station of 5G and of 4G
UPFUser Plane Function: the node of the 5G core network that carries the traffic of the devices
N3, S1-U, N6The 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
TunnelThe path of one PDU session of 5G, or of one bearer of 4G (an E-RAB), between two GTP-U nodes
TEIDTunnel 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-PDUThe GTP-U message that carries one packet of a device, here an IP packet
QFIQoS Flow Identifier: the 6 bits that name the QoS flow of a packet in a 5G tunnel
PDU Session ContainerThe extension header of a G-PDU that carries the QFI on N3 (TS 38.415)
Echo, Error Indication, End MarkerThe 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
TUNA network interface of Linux whose packets a program reads and writes
TCXThe 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

Modules§

ebpfLinux and ebpf
The eBPF fast path of an Endpoint’s tunnels.
tunLinux and tun
Linux TUN devices and their routing, for UE and UPF sessions.
upf_simendpoint
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. UpfSimulator is an N3 peer whose sessions are set with set_session. Uplink packets go to the echo service, which reflects IPv4 UDP and answers ICMP Echo Requests, or to the TUN that attach_tun gives the session. set_echo_service turns the echo service off, for a program that answers the UE itself. send_downlink sends a packet to the UE. The receiver of bind observes 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.
DownlinkPduSessionInformation
DL PDU SESSION INFORMATION (TS 38.415 §5.5.2.1). Time stamps are 64-bit NTP timestamps (RFC 5905 §6).
DownlinkPduSetInformation
DL PDU SET INFORMATION (TS 38.415 §6.5.2.1).
Endpointendpoint
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.
ExtensionHeaderType
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.
ExtensionHeaders
The extension headers of a message, in their order on the wire (TS 29.281 §5.2).
ExtensionHeadersIntoIter
The headers of an ExtensionHeaders, taken out of it in their order: what its into_iter returns.
IcmpEcho
A parsed IPv4 ICMP Echo message.
InformationElementType
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).
MessageType
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.
PathStateendpoint
The state of a path that an endpoint supervises (Endpoint::supervise).
PathTimersendpoint
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).
ReceiveStatsendpoint
Individually sampled receive counters shared by all clones of an endpoint.
ReceivedPacketendpoint
A message for one of the endpoint’s tunnels.
RemoteTunnelendpoint
The far end of a tunnel: the peer’s GTP-U address and the TEID it assigned (an F-TEID). Debug prints the TEID in hexadecimal.
UnknownNewIes
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).
UplinkPduSessionInformation
UL PDU SESSION INFORMATION (TS 38.415 §5.5.2.2). Time stamps are 64-bit NTP timestamps (RFC 5905 §6).
UplinkTimeStamps
The QoS monitoring time stamps of UL PDU Session Information.

Enums§

EchoKind
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).
ExtensionHeader
A GTP-U extension header (TS 29.281 §5.2).
InformationElement
A GTP-U information element (TS 29.281 §8).
Part
The part of a message that an Error is about.
PathEventendpoint
What an endpoint learns of its paths, from the receiver of Endpoint::path_events.
PduSessionContainer
The content of a PDU Session Container (TS 38.415 §5.5.2).
PduSetInformationContainer
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 source to destination.
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.