核心数据结构
struct socket
struct proto_ops
struct sock
struct proto
结构体之间的关系
socket创建
注册struct net_proto_family与struct inet_protosw
static const struct net_proto_family inet_family_ops = {
.family = PF_INET,
.create = inet_create,
.owner = THIS_MODULE,
};
static struct inet_protosw inetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = IPPROTO_TCP,
.prot = &tcp_prot,
.ops = &inet_stream_ops,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT |
INET_PROTOSW_ICSK,
},
{
.type = SOCK_DGRAM,
.protocol = IPPROTO_UDP,
.prot = &udp_prot,
.ops = &inet_dgram_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_PERMANENT,
},
{
.type = SOCK_DGRAM,
.protocol = IPPROTO_ICMP,
.prot = &ping_prot,
.ops = &inet_dgram_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
},
{
.type = SOCK_RAW,
.protocol = IPPROTO_IP, /* wild card */
.prot = &raw_prot,
.ops = &inet_sockraw_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
}
};
fs_initcall(inet_init);
(void)sock_register(&inet_family_ops);
for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
在struct inet_protosw inetsw_array[]数组中的每个元素的struct proto_ops和struct proto都会被初始化,并且通过inet_register_protosw将数组中的每个元素注册到全局static struct list_head inetsw[SOCK_MAX];
sys_socket
sys_socket
sock_create
__sock_create
struct socket *sock = sock_alloc
//下面这个inet_create是之前通过sock_register注册的inet_family_ops中的create函数
pf->create(net, sock, protocol) == inet_create
//在inet_create这个函数中会将之前通过inet_register_protosw
//注册的inetsw_array数组中的struct proto_ops和struct proto
//分别赋值给struct socket和struct sock
sock->ops = answer->ops
struct sock *sk = sk_alloc
sk->sk_prot = sk->sk_prot_create = answer->prot
struct proto_ops
对应tcp的struct proto_ops位于net/ipv4/af_inet.c
const struct proto_ops inet_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release = inet_release,
.bind = inet_bind,
.connect = inet_stream_connect,
.socketpair = sock_no_socketpair,
.accept = inet_accept,
.getname = inet_getname,
.poll = tcp_poll,
.ioctl = inet_ioctl,
.listen = inet_listen,
.shutdown = inet_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
.splice_read = tcp_splice_read,
};
sock_sendmsg
sock_sendmsg位于net/socket.c文件
sock_sendmsg
__sock_sendmsg
struct socket *sock;
sock->ops->sendmsg //这个ops是struct socket结构体中的struct proto_ops
inet_sendmsg
struct sock *sk = sock->sk;
sk->sk_prot->sendmsg //这个ops是struct sock结构体中的struct proto
sock_recvmsg
sock_recvmsg位于net/socket.c文件
sock_recvmsg
__sock_recvmsg
struct socket *sock;
sock->ops->recvmsg //这个ops是struct socket结构体中的struct proto_ops
sock_common_recvmsg
struct sock *sk = sock->sk;
sk->sk_prot->recvmsg //这个ops是struct sock结构体中的struct proto