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?
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
There are four arguments in proto_ops::accept
struct proto_ops {
...
int (*accept) (struct socket *sock,
struct socket *newsock, int flags, bool kern);
};
See: https://elixir.bootlin.com/linux/latest/source/include/linux/net.h#L147
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With