You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Incorrect handling of DL UE UDP traffic with dst port = 2152 #595
DL UDP traffic from Internet to the UE with dst_port 2152 (GTPU port) is wrongly handled as if it was GTPU traffic towards eUPF.
To Reproduce
An UE creates a gtpu session, let's say it gets allocated UE_ADDR=192.168.0.1, and a GTP-U tunnel ENB=<addr=10.0.0.2, teid=0x12345678>, UPF=<addr=10.0.0.1, teid=0x00000001>
UE decides to send whatever UDP traffic he wants to send to an external server on the internet, let's say SERVER_ADDR=8.8.8.8. It wishes to use local UDP port 2152 (yes, the same as the one used by GTPv1U).
eUPF gets the UDP packet towards SERVER_ADDR on top of the GTPU packet, decapsulates it and forwards it to the server. This all works well.
Server answers back to the use, by sending a UDP packet by swapping src_addr and dst_addr, hence dst_addr=UE_ADDR and dst_port=2152.
eUPF gets the UDP packet with dst_addr=UE_ADDR and dst_port=2152, thinks (wrongly) it's a GTPU packet, tries to decode it as GTPU and eventually decides it has to pass it to the kernel (XDP_PASS) since it doens't match any traffic.
Expected behavior
On step 5, eUPF should, first of all, figure out, based on dst IP address of the received UDP packet, whether the packet is targets towards itself (dst_address matches any of the local N3/N9 IP addresses configured), or whether it is aimed at a UE.
The problem in code is here:
diff --git a/cmd/ebpf/xdp/n3n6_entrypoint.c b/cmd/ebpf/xdp/n3n6_entrypoint.c
index a8a16ca..34244b6 100644
--- a/cmd/ebpf/xdp/n3n6_entrypoint.c
+++ b/cmd/ebpf/xdp/n3n6_entrypoint.c
@@ -398,7 +398,7 @@ static __always_inline enum xdp_action handle_ip4(struct packet_context *ctx) {
}
case IPPROTO_UDP:
increment_counter(ctx->counters, rx_udp);
- if (GTP_UDP_PORT == parse_udp(ctx)) {
+ if (GTP_UDP_PORT == parse_udp(ctx)) { //HERE: also match dst IP address N3/N9...
upf_printk("upf: gtp-u received");
increment_counter(ctx->n3_n6_counter, rx_n3);
return handle_gtpu(ctx);
But there is an impediment. Data plane eBPF program has no info about N3/N9 address currently. I'm planning to add configurable during startup parameters like N3/N9 address using static variables. Now in cilium library there is an option to use static variables as kind of maps.
@pirog-spb thanks for looking into this. FYI this kind of degrades some of the UPF benchmarking I'm doing currently with 200K sessions and 100 emulated eNBS with TRex, since some of the sessions created by TRex may contain that port and traffic ends up dropped for those sessions.
It's common practice to configure N3+N9 and N6 on two separate netifs.
This way, you can bind the uplink BPF program on the N3+N9 netif, and bind the downlink BPF program on the N6 netif.
It's common practice to configure N3+N9 and N6 on two separate netifs. This way, you can bind the uplink BPF program on the N3+N9 netif, and bind the downlink BPF program on the N6 netif.
Exactly. Initially eUPF designed to be cloud-native. So target deployment mode was UPF-on-a-stick. But in some cases it'd be much more easier to attach different ebpf N3 and N6 programs on different network interfaces. We have N3 and N6 ebpf stubs, but implementation is still in roadmap.
Activity
pirog-spb commentedon Mar 1, 2025
Hi @pespin
Good point. Should be fixed without any doubts.
But there is an impediment. Data plane eBPF program has no info about N3/N9 address currently. I'm planning to add configurable during startup parameters like N3/N9 address using static variables. Now in cilium library there is an option to use static variables as kind of maps.
-- BR Alex
pirog-spb commentedon Mar 1, 2025
See #398
pespin commentedon Mar 3, 2025
@pirog-spb thanks for looking into this. FYI this kind of degrades some of the UPF benchmarking I'm doing currently with 200K sessions and 100 emulated eNBS with TRex, since some of the sessions created by TRex may contain that port and traffic ends up dropped for those sessions.
yoursunny commentedon Mar 31, 2025
It's common practice to configure N3+N9 and N6 on two separate netifs.
This way, you can bind the uplink BPF program on the N3+N9 netif, and bind the downlink BPF program on the N6 netif.
pirog-spb commentedon Mar 31, 2025
Exactly. Initially eUPF designed to be cloud-native. So target deployment mode was UPF-on-a-stick. But in some cases it'd be much more easier to attach different ebpf N3 and N6 programs on different network interfaces. We have N3 and N6 ebpf stubs, but implementation is still in roadmap.
-- BR, Alex