linuxsocketslinux-kernelfunction-pointersgetsockopt

Where do the function pointers point to in struct "proto_ops"?


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!


Solution

  • 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.