Appearance
How eBPF Detects Control-Plane Protocol Violations Inside GTP-U Tunnels
There is a boundary in 5G that looks obvious on paper.
The user plane carries subscriber traffic. The control plane manages mobility, session state, policy, charging, and forwarding rules. GTP-U carries user-plane packets between the RAN and the UPF. PFCP controls the UPF from the SMF. NGAP connects the gNB to the AMF. F1AP, E1AP, XnAP, and E2AP belong to RAN control interfaces.
Those boundaries are the architecture.
But the architecture is not the running system.
In a virtualized 5G deployment, the same Linux hosts and Kubernetes nodes may carry gNB traffic, UPF traffic, PFCP, SBI, CNI forwarding, service routing, host networking, and application processes. Packets that are cleanly separated in a 3GPP diagram become bytes moving through interfaces, namespaces, routes, sockets, and tunnel headers. When something crosses the wrong boundary, application logs may only show a failed parse, a closed socket, or nothing at all.
The case below follows one of those crossings from the packet to the runtime evidence. A crafted GTP-U G-PDU used a tunnel identifier and carried an inner UDP packet targeting PFCP on port 8805. The outer packet looked like normal GTP-U user-plane traffic between a gNB-side node and a UPF. The inner packet targeted the SMF-side PFCP interface. That combination is the security finding. The outer layer says user plane. The inner destination says control plane.
Telovix captured the violation as a critical runtime event:
text
event_kind=gtpu_control_plane_tunneling_attack
severity=critical
GTP-U tunneling attack: TEID=0x00009831 outer 192.168.128.33>192.168.128.31
carries udp inner 10.45.0.4>192.168.128.32:8805 targeting N4/PFCP
-- control-plane protocol encapsulated in user-plane tunnelThat sentence is the whole story in telecom language. The packet belonged to GTP-U from the outside, it carried TEID 0x00009831, it moved from 192.168.128.33 to the UPF at 192.168.128.31, and inside the tunnel it carried traffic from the UE-side address 10.45.0.4 toward 192.168.128.32:8805, the PFCP control-plane interface.
This is a different class of evidence from a port scan, a firewall hit, or a generic packet alert. It says traffic targeting a control-plane interface appeared where it should not appear: inside a user-plane tunnel.
Architectural Boundary
Most security teams have a mental model for segmentation. The UE belongs to subscriber space. GTP-U belongs to N3 or N9 user-plane transport. PFCP belongs to N4 control-plane transport. NGAP belongs to N2 control-plane transport. SBI belongs to internal 5G Core service communication. Kubernetes APIs, databases, node services, and management endpoints belong to the platform plane.
Those categories are useful, but they are static. They describe the architecture at design time. They do not automatically prove that the running system still preserves the same separation once traffic passes through Linux hosts, Kubernetes overlays, CNI forwarding, service routing, namespaces, tunnels, and network functions running as ordinary processes.
An attacker does not have to respect interface diagrams. A rogue RAN-side workload, compromised gNB process, misused traffic generator, malicious component, or host process with packet-sending capability can generate bytes that look valid enough to traverse one layer while violating another. If user-plane encapsulation carries an inner packet that targets a control-plane service, the network has a boundary problem before anyone proves parser exploitation, authentication bypass, or session manipulation.
This distinction is important. A PFCP service might reject malformed input. An AMF might reject invalid NGAP or NAS. A RIC might reject malformed E2AP. Those outcomes are useful, but they do not erase the more basic security fact: traffic from the wrong plane reached the wrong semantic destination. Rejection by an application is not the same thing as preservation of a telecom boundary.
This article focuses on that boundary, not on crashing Open5GS, manipulating PFCP state, or fuzzing a parser. The research question is narrower and more fundamental: can a control-plane destination appear inside a GTP-U user-plane tunnel, and can runtime evidence prove the violation at TEID level?
Lab Setup And Threat Model
The lab used a virtualized 5G network with Open5GS, simulated UEs, a gNB-side workload, a UPF, an SMF, and Telovix sensors running as a DaemonSet. The path was intentionally small enough to reason about directly. The RAN-side host used 192.168.128.33. The UPF used 192.168.128.31 for GTP-U on UDP 2152. The SMF used 192.168.128.32 for PFCP on UDP 8805. The UE-side source inside the tunnel was 10.45.0.4.
The packet therefore had two meanings. At the outer layer, it was ordinary-looking GTP-U traffic on the user-plane path:
text
192.168.128.33 -> 192.168.128.31:2152/udp
GTP-U G-PDU
TEID 0x00009831At the inner layer, it targeted a control-plane destination:
text
10.45.0.4 -> 192.168.128.32:8805/udp
N4/PFCP control-plane destinationThose two facts should not be true at the same time. GTP-U is the user-plane tunnel. PFCP is the control protocol used by the SMF to manage UPF forwarding behavior. A packet that is user plane on the outside and PFCP-directed on the inside is not merely unusual UDP. It is a semantic boundary violation.

The topology view grounds the case in the running environment rather than in an abstract diagram. The UE address 10.45.0.4 is visible, the gNB is on the RAN side, and the UPF sits on the user-plane path. The test assumes only that an attacker or tester can originate packets from a RAN-side or UE-adjacent environment. In a reproduction environment, that can be a traffic generator or simulated UE environment. In a compromised deployment, it could be a rogue gNB-side workload, a compromised RAN pod, a helper process on a host, or any process with enough network access to send UDP toward the UPF.
The test does not assume valid PFCP command execution. It does not assume authentication bypass. It does not assume successful session modification. It does not assume a crash. That narrowness is deliberate. It keeps the reproduction safe while making the evidence stronger. The finding is about boundary integrity rather than payload success.
Experiment Design
The suspicious pattern is simple, a packet arrives as GTP-U on UDP 2152, the GTP-U message is a G-PDU, and the inner packet targets a telecom control-plane interface. In this case the inner destination was 8805/udp, which maps to N4/PFCP. The same detection principle applies to NGAP on SCTP 38412, F1AP on SCTP 38472, E1AP on SCTP 38462, XnAP on SCTP 38422, E2AP on SCTP 36421, Diameter on 3868, and GTPv2-C on UDP 2123.
The exact protocol matters less than the invariant. Control-plane ports should not appear as inner destinations inside GTP-U user-plane payloads. When they do, the system is no longer behaving like the architecture says it should.
The test packet was deliberately small. It was not a valid PFCP session modification. It was not a fuzzing payload. It was not exploit code. It was a minimal GTP-U G-PDU with an inner IPv4/UDP packet whose destination port was 8805. The outer header carried GTP-U from 192.168.128.33 to 192.168.128.31:2152. The GTP-U header used message type 0xff, the G-PDU type, and TEID 0x00009831. The inner IPv4 packet used 10.45.0.4 as the source and 192.168.128.32:8805 as the destination. The payload was only a lab marker.
That marker was not important. The detector does not need a valid PFCP message to prove the boundary violation. It needs the packet structure to show that a PFCP-directed destination appeared inside a GTP-U T-PDU. This is a useful safety property for research as it allows the boundary to be tested without sending destructive PFCP messages.
The reproduction ran on May 21, 2026. The packet was sent from the simulated RAN/UE side toward the UPF. The test emitted a clear start and end marker so runtime events could be correlated with the injection window:
text
TELOVIX_GTPU_CP_TUNNEL_TEST_START 2026-05-21T04:21:35Z
sent_pfcp_inner_1
sent_pfcp_inner_2
sent_pfcp_inner_3
TELOVIX_GTPU_CP_TUNNEL_TEST_END 2026-05-21T04:21:44ZRuntime Evidence
The data in this article comes from packet injection, the Telovix eBPF sensor, and the Telovix Console analytics. During the test window, three small GTP-U packets were sent toward the UPF. The sensor observed UDP 2152, parsed the GTP-U header, extracted the TEID, parsed the inner IP header when the message was a G-PDU, and checked whether the inner destination belonged to a control-plane interface. After the test, the event stream was queried for gtpu_control_plane_tunneling_attack, GTP-U tunneling attack, N4/PFCP, and TEID=0x00009831.
The first detection appeared immediately on the UPF-side node:
text
observed_at = 2026-05-21 04:21:35.438
event_kind = gtpu_control_plane_tunneling_attack
severity = critical
node_name = aux-worker-1
sensor_id = sensor_CYolkLZ77xAVckqqThe event message carried the important telecom evidence:
text
GTP-U tunneling attack: TEID=0x00009831 outer 192.168.128.33>192.168.128.31
carries udp inner 10.45.0.4>192.168.128.32:8805 targeting N4/PFCP
-- control-plane protocol encapsulated in user-plane tunnelThe same violation was also seen from the gNB-side node at 2026-05-21 04:21:35.515, with sensor sensor_LXLjZ1bTaInVMzxx on aux-worker-3. A later observation appeared again on the UPF-side node at 2026-05-21 04:21:38.446. That matters because the event was not inferred from one endpoint only. It was visible from both sides of the GTP-U path: the gNB-side sensor saw the violation from the RAN side, and the UPF-side sensor saw it where the tunnel arrived.

The event search is the first hard evidence view. It shows the runtime analytics result set filtered to gtpu_control_plane_tunneling_attack, with critical events on aux-worker-1 during the test window. This is where packet crafting becomes stored runtime evidence.

This event detail here is the strongest as it shows the attack chain and the detection reason as an analyst would read it: TEID 0x00009831, outer GTP-U path 192.168.128.33 > 192.168.128.31, inner packet 10.45.0.4 > 192.168.128.32:8805, and target interface N4/PFCP. That is the core evidence chain.
Detector Semantics
At the capture layer, the sensor watches packets where either the source port or destination port is GTP-U port 2152. When it sees a candidate packet, it parses the GTP-U header and checks whether the message is a G-PDU. A G-PDU is important because it carries the user-plane payload.
If an inner packet exists, the sensor parses the inner IP header and extracts the inner protocol and destination port. SCTP and UDP are the relevant protocols for the telecom control-plane interfaces in this detector. If the inner destination port is one of the known control-plane ports, the sensor emits a critical event.
In plain language, the detector is looking for a broken invariant:
text
If GTP-U carries an inner SCTP or UDP packet whose destination is a telecom control-plane port,
then the user-plane tunnel is carrying traffic toward a control-plane interface and the event should be critical.The output is not a generic alert. It is an evidence record. It tells the operator which TEID carried the packet, which GTP-U endpoints formed the outer path, which inner source and destination were present, which control-plane port was targeted, which interface name that port maps to, and which sensor observed the packet. A generic tool can say UDP 2152 was active. A packet analyzer can show GTP-U bytes. A telecom-aware runtime sensor can say that a user-plane TEID carried a packet to N4/PFCP.
A network function log may not show this clearly. If the target service rejects the packet, the log might only show a parser error. If routing drops it, there may be no application log. If forwarding rewrites the source, the log may show a peer that hides the original path. If the payload is malformed, the target may not record useful metadata. If the packet crosses the GTP-U boundary but never reaches the target process, the application may never know. The runtime detector does not need PFCP to accept the message. It only needs to see the GTP-U G-PDU, the inner packet, and the control-plane destination.
TEID-Level Investigation
The TEID is the difference between a generic packet alert and a telecom investigation. Without the TEID, the finding would only say that a suspicious UDP packet was present. With the TEID, the finding says that GTP-U tunnel 0x00009831 carried traffic toward N4/PFCP.
That changes the investigation. The operator can ask whether this TEID was part of an active UE session, which gNB-side endpoint used it, which UPF saw it, whether normal user traffic used the same TEID before or after the event, whether matching PFCP session state existed, whether the outer peer was expected, whether the inner destination was the real SMF or a spoofed control-plane address, and whether the event appeared after a restart, peer drift, or tunnel churn. These are not generic cloud questions. They are 5G runtime questions.

The user-plane view is the bridge between the critical detection and the surrounding tunnel state. It shows GTP-U tunnel events, including orphan TEID evidence for 0x00009831, and the tunnel activity table where the same TEID appears with peer IPs, UE-side addresses, packet counts, byte volume, first-seen timing, and last-seen timing. This moves the investigation beyond one alert. The event sits inside an observable TEID lifecycle.
This is where telecom runtime security differs from generic workload monitoring. The sensor is not only looking for malicious strings or known CVEs. It is watching invariants. A user-plane tunnel should not carry traffic toward control-plane interfaces. PFCP direction should match SMF and UPF roles. TEID peers should match expected RAN and user-plane endpoints. Control-plane ports should not appear as inner user-plane destinations. When one of those invariants breaks, the alert carries context that an operator can investigate in telecom terms.
Operational Meaning
In the same environment, simple reachability from UE space to internal services was also possible. That finding was operationally useful, but it was not the strongest research topic. Reachability can come from routing mistakes, permissive policies, Kubernetes service exposure, or testbed convenience. This case is different because it does not ask whether a UE can connect to an internal IP. It asks whether traffic targeting a control-plane interface can appear inside user-plane encapsulation.
That is a stronger security perspective. A port scan is an IP and port observation. This is a telecom semantic violation. The evidence is not only source and destination. It includes TEID, GTP-U outer path, inner packet, target interface, and the violated boundary between user plane and control plane. The result reads less like "this service was reachable" and more like "this user-plane tunnel carried a packet toward a control-plane interface."
This result belongs to a broader family of 5G security problems where interface confusion, boundary bridging, and runtime behavior that does not preserve the assumptions of the standard architecture. Recent telecom research has repeatedly shown that practical attacks often emerge where implementation behavior crosses an assumed boundary. RAN-core fuzzing explores what happens when malformed or adversarial signaling reaches core functions. UE capability downgrade work studies how device and network negotiation can expose security weaknesses. Context integrity research studies how procedure chains can affect state they should not control. User-plane boundary research looks at how forwarding paths can reach places the architecture did not intend.
The control-plane-inside-GTP-U pattern crosses two assumptions at once. GTP-U is treated as user-plane encapsulation, while PFCP, NGAP, F1AP, E1AP, XnAP, and E2AP are treated as control-plane interfaces. When a control-plane destination appears inside a GTP-U payload, the first security fact is already visible. Whether the destination accepts, rejects, or drops the packet is the next question.
For this class of event, the Console should avoid generic alert language. The analyst should not have to decode packet bytes to understand the finding. The event should say directly that traffic targeting a control-plane interface appeared inside a GTP-U user-plane tunnel. It should show TEID 0x00009831, the outer path 192.168.128.33 -> 192.168.128.31, the inner path 10.45.0.4 -> 192.168.128.32:8805/udp, the target interface N4/PFCP, and the sensors that observed the event on aux-worker-1 and aux-worker-3.
Defensive Guidance
The defensive answer is not one control. It is a set of controls that preserve the architecture boundary.
User-plane decapsulation paths should enforce destination policy. Inner GTP-U packets should not be allowed to target PFCP on 8805, NGAP on 38412, F1AP on 38472, E1AP on 38462, XnAP on 38422, E2AP on 36421, Diameter on 3868, or GTPv2-C on 2123. If these destinations are visible inside GTP-U, the monitoring layer should treat the event as a boundary violation.
Forwarding policy should also restrict where UE-originated or tunnel-carried traffic can go. Subscriber traffic should not route freely into Kubernetes service CIDRs, Kubernetes pod CIDRs, node management networks, 5G Core control-plane addresses, databases, SBI endpoints, RIC interfaces, CU/DU control interfaces, or OAM services unless the operator has a very explicit reason.
The UPF and GTP-U endpoints should validate peers. A UPF should know which RAN or peer UPF addresses are expected. Unexpected GTP-U peers, sudden TEID churn, TEID spray, orphan TEIDs after restart, and control-plane destinations inside user-plane payloads should all be treated as related evidence, not isolated counters.
Control-plane services should not rely only on being internal. PFCP, SBI, NGAP, and RAN control interfaces need network policy, peer identity, runtime monitoring, and evidence retention. The important detection is not that UDP 2152 was active. The important detection is that a GTP-U user-plane tunnel carried traffic to a control-plane interface.
Limitations And Follow-Up Work
This is not a claim that every production network is vulnerable. The packet was intentionally minimal. It carried a PFCP-directed inner UDP packet, but it was not a complete PFCP exploit. The result proves that the detector can identify the boundary violation and that this path allowed the packet to be observed. It does not prove successful PFCP state manipulation.
This reproduction used Open5GS and simulated UEs, but production systems may use different UPF implementations, different tunnel handling, different routing controls, and different packet paths. The method should be adapted to each environment. Visibility also matters. If a UPF uses a full kernel-bypass path such as DPDK, VFIO, or AF_XDP without mirrored visibility, an eBPF sensor may not see all user-plane packets. In that case, the right finding is a visibility gap, not a clean bill of health. Silent blindness is worse than an explicit visibility gap.
Conclusion
The experiment started with a simple idea: what if the user plane carries something that only belongs to the control plane?
The answer was visible in a single critical event:
text
GTP-U tunneling attack: TEID=0x00009831 outer 192.168.128.33>192.168.128.31
carries udp inner 10.45.0.4>192.168.128.32:8805 targeting N4/PFCPThat sentence contains the story. A user-plane tunnel existed. A TEID carried the packet. The outer path looked like RAN-to-UPF GTP-U. The inner path targeted PFCP. The destination interface was N4. The event was detected from runtime evidence.
The most valuable security signals in a telecom network are often not generic Linux signals. They are violations of telecom meaning. A process opening a socket is generic. An SMF sending PFCP to a UPF is expected telecom behavior. A UPF receiving GTP-U on UDP 2152 is expected telecom behavior. A GTP-U TEID carrying an inner packet to PFCP 8805 is not expected telecom behavior.
That is the difference between monitoring packets and understanding a running 5G system. The diagram says the user plane and control plane are separate. Runtime evidence tells us whether they stayed separate.