Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

socket: properly support SO_ATTACH_FILTER sockopt #274

Merged
merged 1 commit into from
Feb 4, 2025

Conversation

jow-
Copy link
Owner

@jow- jow- commented Feb 3, 2025

The SO_ATTACH_FILTER socket option requires special handling as it is not passing a self-contained structure to the kernel but a pointer to user memory holding the actual BPF bytecode.

In order to properly support this, first rework the ucode value to C struct conversion callback machinery to pass an indirect struct base pointer, allowing conversion callbacks to realloc the struct memory as needed.

Finally introduce custom uv to C conversion for the BPF data which accepts either a raw bytecode string, an array of opcode arrays or a flat array of opcode values which are converted into a C array of struct sock_filter records appended to the reallocated struct memory.

Attaching a BPF program equivalent to the tcpdump expression vlan 20 && ether proto 0x1234 would then look like this:

sock.setopt(SOL_SOCKET, SO_ATTACH_FILTER, {
  filter: [
    [ 0x28, 0, 0, 0x0000000c ],
    [ 0x15, 2, 0, 0x00008100 ],
    [ 0x15, 1, 0, 0x000088a8 ],
    [ 0x15, 0, 6, 0x00009100 ],
    [ 0x28, 0, 0, 0x0000000e ],
    [ 0x54, 0, 0, 0x00000fff ],
    [ 0x15, 0, 3, 0x00000014 ],
    [ 0x28, 0, 0, 0x00000010 ],
    [ 0x15, 0, 1, 0x00001234 ],
    [ 0x6, 0, 0, 0x00040000 ],
    [ 0x6, 0, 0, 0x00000000 ],
  ]
});

The SO_ATTACH_FILTER socket option requires special handling as it is not
passing a self-contained structure to the kernel but a pointer to user
memory holding the actual BPF bytecode.

In order to properly support this, first rework the ucode value to C struct
conversion callback machinery to pass an indirect struct base pointer,
allowing conversion callbacks to realloc the struct memory as needed.

Finally introduce custom uv to C conversion for the BPF data which accepts
either a raw bytecode string, an array of opcode arrays or a flat array of
opcode values which are converted into a C array of struct sock_filter
records appended to the reallocated struct memory.

Attaching a BPF program equivalent to the tcpdump expression
`vlan 20 && ether proto 0x1234` would then look like this:

    sock.setopt(SOL_SOCKET, SO_ATTACH_FILTER, {
      filter: [
        [ 0x28, 0, 0, 0x0000000c ],
        [ 0x15, 2, 0, 0x00008100 ],
        [ 0x15, 1, 0, 0x000088a8 ],
        [ 0x15, 0, 6, 0x00009100 ],
        [ 0x28, 0, 0, 0x0000000e ],
        [ 0x54, 0, 0, 0x00000fff ],
        [ 0x15, 0, 3, 0x00000014 ],
        [ 0x28, 0, 0, 0x00000010 ],
        [ 0x15, 0, 1, 0x00001234 ],
        [ 0x6, 0, 0, 0x00040000 ],
        [ 0x6, 0, 0, 0x00000000 ],
      ]
    });

Signed-off-by: Jo-Philipp Wich <[email protected]>
@jow- jow- force-pushed the socket-filter-sockopt-support branch from 1f810a6 to 001ced1 Compare February 4, 2025 09:21
@jow- jow- merged commit 80939e3 into master Feb 4, 2025
3 checks passed
@jow- jow- deleted the socket-filter-sockopt-support branch February 4, 2025 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant