Search code examples
linux-kernelebpfbpf

Is it possible to create and send a packet from a bpf program?


Idea: The first way is to create a brand-new packet in the bpf program and send it to the specified receiver. The second way is to copy a packet. To make it easy to distinguish, below I call the packet I get from copying as packet_copy. Then I can modify the packet_copy so it can be sent to the specified receiver, and the original packet will go through the normal path.

Try: As to the first way, I have not found a suitable solution, but someone says that this way is not possible. As to the second way, I found bpf_clone_redirect() as a possible solution. However, instead of getting the packet_copy from copying, we should directly modify the original packet (so that it can be redirected to the specified receiver) and then call bpf_clone_redirect to redirect it. I also need to undo the modification to restore the packet after calling bpf_clone_redirect because I want this packet to be processed normally rather than dropped.

Question: As to the first way, I would like to know if it is feasible. As to the second way, I wonder if it can be optimized, given that bpf_clone_redirect has its limitations.


Solution

  • The first way is to create a brand-new packet in the bpf program and send it to the specified receiver.

    That is indeed not possible today. It would require dynamic memory allocation to allocate memory for the packet and a helper to then send the packet out. None of these are available in BPF today (v5.19).

    However, instead of getting the packet_copy from copying, we should directly modify the original packet (so that it can be redirected to the specified receiver) and then call bpf_clone_redirect to redirect it. I also need to undo the modification to restore the packet after calling bpf_clone_redirect because I want this packet to be processed normally rather than dropped.

    I don't know of a more efficient way in a single BPF program.

    Depending on where in the stack you sit, you may however be able to use two BPF programs, with one doing the cloning and another one intercepting one of the copies after to modify it. I'm not convinced that would be more CPU efficient but it may be cleaner.