Search code examples
csocketslinux-kernelkernel-moduleunix-socket

Why do I get "error: too few arguments to function ‘sock->ops->accept’"


I am writing kernel module with sockets. When I try write code for accept connection I get:

"error: too few arguments to function ‘sock->ops->accept’ ret = sock->ops->accept(sock, client_sock, 0);"

I looked into implementation of socket accept and there are only three arguments so I don't know what's going on.

struct socket *sock = NULL, *client_sock = NULL;
//some code here, create socket, bind, listen
ret = sock->ops->accept(sock, client_sock, 0);

I expect that it should works but it doesn't. Why do I get "too few arguments" error if in implementation are only three? How can I fix that?


Solution

  • The prototype of the ->accept() handler was changed between kernel versions 4.10 and 4.11 by this commit: "net: Work around lockdep limitation in sockets that use sockets".

    As mentioned in user MofX's answer, the ->accept() handler has a fourth parameter bool kern in current kernel versions (since 4.11). According to the commit description, this is analogous to the kern parameter passed in to ->create(), and distinguishes whether kernel_accept() or sys_accept4() was the caller. See the commit description for details.

    If you want your code to work for kernels both before and since 4.11, you will need to use conditional compilation:

    #include <linux/version.h>
    
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
    #define KV_ACCEPT_HAS_BOOL_KERN
    #endif
    
    #ifdef KV_ACCEPT_HAS_BOOL_KERN
        // your code needs to determine whether 'kern' should be false or true here...
        ret = sock->ops->accept(sock, client_sock, 0, kern);
    #else
        ret = sock->ops->accept(sock, client_sock, 0);
    #endif