In Linux kernel, I find the system call getsockopt
finally calls sock->ops->getsockopt
(code here). And sock->ops
is a struct called proto_ops
. This struct contains many function pointers such as getsockopt
and I am wondering where it points to - I didn't find the place initiates this struct.
I'm using IPv4 and TCP for the system call and it may have some certain implementation functions to call here.
Any insights would be extremely helpful. Thanks in advance!
For an IPv4 socket, the ops will be one of the structures inet_stream_ops
, inet_dgram_ops
, inet_sockraw_ops
defined in net/ipv4/af_inet.c
(unless you're using something weird like SCTP that has its own ops defined elsewhere). To see how those pointers get there, look at inet_create
in the same file, which is called from __sock_create
as pf->create()
.
To see how that pointer gets there, note that inet_create
is the create
member of a struct called inet_family_ops
which is passed to sock_register()
, causing it to be placed in the net_families
array which is consulted when a socket is created.
Functions with register
in their names are a good thing to look for when you want to see how different kernel components are connected.
Now back to getsockopt
. If you look at where the getsockopt
pointer actually goes, in all 3 of the inet_*_ops
structs it points to sock_common_getsockopt
for the getsockopt
function.
sock_common_getsockopt
in net/core/sock.c
isn't very interesting. It just extracts a struct sock
from a struct socket
and then calls sk->sk_prot->getsockopt
. So next you'll be wondering where that comes from.
It comes from the next layer up. I'm going to assume TCP as an example.
In net/ipv4/tcp_ipv4.c
there's a struct proto tcp_prot
in which the getsockopt
member points to tcp_getsockopt
, a function defined in net/ipv4/tcp.c
. It implements SOL_TCP
options itself, and for others, it calls the getsockopt
method from another ops structure called icsk_af_ops
. That brings us back to net/ipv4/tcp_ipv4.c
where struct inet_connection_sock_af_ops ipv4_specific
has getsockopt
pointing to ip_getsockopt
.
ip_getsockopt
is in net/ipv4/ip_sockglue.c
and it calls do_ip_getsockopt
in the same file, which is where the SOL_IP
options are actually handled.