edgecomllc / eupf

5G User Plane Function (UPF) based on eBPF
Apache License 2.0
100 stars 20 forks source link

Some issues with eUPF eBPF's Go interface #477

Closed linouxis9 closed 10 months ago

linouxis9 commented 10 months ago

Describe the bug

I'm interested in contributing a PR if you have some pointers on what the issue could be. Thanks!

To Reproduce Steps to reproduce the behavior:

  1. Insert a PDR inside bpfObjects using bpfObjects.PutPdrUpLink after a ResizeAllMaps, and inspect the maps using bpftool.
  2. Insert a PDR inside bpfObjects using bpfObjects.PutDownlink , and inspect the maps using bpftool.

Expected behavior eBPF maps are filled and can be used by the eBPF programs.

Environment (please complete the following information):

Additional context The eBPF code is used outside eUPF as part of a gNodeB simulator. Context on what I'm trying to achieve: https://github.com/edgecomllc/eupf/discussions/469

pirog-spb commented 10 months ago

Hi @linouxis9,

The problem occures only after ResizeAllMaps is called? I advice not to use ResizeAllMaps. It sometimes doesn't work properly (no values saved in map after resize). Update hardcoded values in the code. This is the only guaranteed way to update maps size at the moment.

#define QER_MAP_SIZE 1024
#define PDR_MAP_UPLINK_SIZE 1024
#define PDR_MAP_DOWNLINK_IPV4_SIZE 1024
#define PDR_MAP_DOWNLINK_IPV6_SIZE 1024
#define FAR_MAP_SIZE 1024
pirog-spb commented 10 months ago

I think we can make these variables updatable during ebpf building process

linouxis9 commented 10 months ago

Hi @pirog-spb!

Thanks for your answer :-)

First issue occurs only after a ResizeMapAll, and indeed, that's exactly what happens: no values saved in map after resize. I'll update the constants in that case, thanks!

Second issue happens even without a ResizeMapAll.

pirog-spb commented 10 months ago

The second point looks strange. bpfObjects.PutPdrDownlink call doesn't update ebpf map pdr_map_downlink_ip4 in your case. Correct? Does it return any error?

linouxis9 commented 10 months ago

Hi @pirog-spb, Correct. Thanks for your help! I just found the issue, there was no error displayed. It was a bit puzzling why it was working to write in the Map directly, but not using the PutPdrDownlink function. The issue was that I was correctly doing bpfObjects.IpEntrypointObjects.PdrMapDownlinkIp4.Put(**netUeIp.To4()**, unsafe.Pointer(&pdrUplink));, but I was inputting directly netUeIp (of type net.IP) to bpfObjects.PutPdrDownlink(**netUeIp**, pdrUplink). Maybe a check should be added in that regard?

FYI: I was able to successfully make use of your eBPF code to do UPF -> simulated gNodeB traffic (using bpfObjects.PutPdrUpLink(gnbPduSession.GetTeidDownlink(), pdrDownlink)). However, I still have some trouble doing the opposite: simulated gNodeB -> UPF (using bpfObjects.PutPdrDownLink(netUeIp.To4(), pdrUplink)). I'm getting this kind of messages in the traces: bpf_trace_printk: upf: no downlink session for ip:A.B.C.D where A.B.C.D is packet's target IP instead of UE's IP address). Will continue investigating!

Cheers and thanks for your help!

pirog-spb commented 10 months ago

Maybe a check should be added in that regard?

What kind of check do you mean?

bpf_trace_printk: upf: no downlink session for ip:A.B.C.D means that ebpf program receive IP packet with destination IP unknown. Program assumes that destination IP should be a UE IP.

linouxis9 commented 10 months ago

Maybe a check should be added in that regard?

What kind of check do you mean?

That the IP slice is correctly 4 bytes on PutPdrDownLink, and 16 bytes on PutPdrDownLink6. The issue I had was net.ParseIP returns an IP on 16 bytes by default if you don't use .To4(), even when parsing an IPv4.

bpf_trace_printk: upf: no downlink session for ip:A.B.C.D means that ebpf program receive IP packet with destination IP unknown. Program assumes that destination IP should be a UE IP.

Thanks a lot! I'll tweak the eBPF code locally for now to check on source IP instead.