libbpf-bootstrap
libbpf-bootstrap copied to clipboard
examples/c: add socket filter example
This is a simplified example I port from linux samples/bpf directory, many code snippet came from there.
In this example, I opened a SOCK_RAW socket in lo interface, then attach it to the bpf program for monitoring.
I use BPF_MAP_TYPE_RINGBUF to carry information back to user space program, and the user space program will print formatted information to stdout, for example:
interface:lo protocol: UDP 127.0.0.1:51845(src) -> 127.0.0.1:53(dst)
interface:lo protocol: UDP 127.0.0.1:41552(src) -> 127.0.0.1:53(dst)
Currently, most of the IPv4 protocols defined in uapi/linux/in.h are included, please check ipproto_mapping for the supported protocols.
Another thing to be done is that we need to add another linux uapi header into libbpf submodule : uapi/linux/ip.h, because we need to retrieve protocol, saddr and daddr from struct ip_hdr.
I will temporarily mark this PR as draft, please give me some suggestions for this, thank you!
In general, have you thought about doing the same thing in tc hook instead? tc is a more popular hook for bpf prog. Also, it should be faster (kernel does not always have to clone the skb) and has more bpf features/helpers. For example, it can directly read skb->data. The tc hook has much more helper to find useful things also. Just name a few, when the tc-bpf prog intercepted an interesting src/dst ip, it can find the sk and print more information about this sk. e.g. the sock cookie and what tcp state it is in...etc.
In general, have you thought about doing the same thing in tc hook instead? tc is a more popular hook for bpf prog. Also, it should be faster (kernel does not always have to clone the skb) and has more bpf features/helpers. For example, it can directly read skb->data. The tc hook has much more helper to find useful things also. Just name a few, when the tc-bpf prog intercepted an interesting src/dst ip, it can find the sk and print more information about this sk. e.g. the sock cookie and what tcp state it is in...etc.
Thanks a bunch for all of these useful information!
Actually I haven't tried this before, but I think we can cover as many bpf program types as possible:
https://github.com/libbpf/libbpf/blob/0e43565ad8b4f7bdfa974916e9d7f800157d06ec/src/libbpf.c#L8445-L8527
Maybe I can add another example for tc bpf program later, what kind of implementation do you think, is suitable for a tc bpf program?
Sorry for delay, looks good. skeleton__attach() isn't necessary (socket programs are not auto-attachable, so it has no effect, I'll drop it and force-push locally, no need to resubmit).
But also (I'm not a big BPF networking expert), at least for some use cases, skb->data and skb->data_end are probably a better approach than more heavyweight bpf_skb_load_bytes(). Have you used data/data_end special pointers before? Do they work in this case? If yes, maybe let's use them at least for some accesses to improve the example and demonstrate both ways of accessing data?
Sorry for delay, looks good. skeleton__attach() isn't necessary (socket programs are not auto-attachable, so it has no effect, I'll drop it and force-push locally, no need to resubmit).
But also (I'm not a big BPF networking expert), at least for some use cases, skb->data and skb->data_end are probably a better approach than more heavyweight bpf_skb_load_bytes(). Have you used data/data_end special pointers before? Do they work in this case? If yes, maybe let's use them at least for some accesses to improve the example and demonstrate both ways of accessing data?
After tracking down linux source code, I thought skb->data and skb->data_end are not accessible in BPF_PROG_TYPE_SOCKET_FILTER, reference: https://github.com/torvalds/linux/blob/072e51356cd5a4a1c12c1020bc054c99b98333df/net/core/filter.c#L8365-L8392
I will try to use this in other examples, thanks a lot for your suggestions!
Very well could be, as I said not a big BPF networking expert here :)
Very well could be, as I said not a big BPF networking expert here :)
It's OK, you looks like an expert to me! Thanks for the information anyway.