ipv4内核初始化分析-sock的创建

2009年11月17日 | 由 helight | 1100字 | 阅读大约需要3分钟 | 归档于 kernel | 标签 #protobuf

sock创建的主要数据结构是下面这个结构体:

static struct net_proto_family inet_family_ops = {
        .family = PF_INET, //这里的值可以是PF_AX25,PF_UNIX,PF_IPX,PF_INET6。。。
	// 这些都在include/linux/socket.h 这个文件中定义了,
        .create = inet_create,                                                                   
        .owner  = THIS_MODULE,
};

从include/linux/socket.h这个里面可以看出,所谓的PF_INET和AF_INET就是一回事,只是叫法不一样而已 AF = Address Family PF = Protocol Family AF_INET = PF_INET   所以,理论上建立socket时是指定协议,应该用PF_xxxx,设置地址时应该用AF_xxxx。当然AF_INET和PF_INET的值是相同的,混用也不会有太大的问题。 在写网络程序的时候,建立TCP socket一般是这样的: sock = socket(PF_INET, SOCK_STREAM, 0);   然后在绑定本地地址或连接远程地址时需要初始化sockaddr_in结构,其中指定address family时一般设置为AF_INET,即使用IP。

static int __init inet_init(void){

(void)sock_register(&inet_family_ops); 

}
static const struct net_proto_family *net_families[NPROTO] __read_mostly;

这里进行了内核socket操作操作的注册

int sock_register(const struct net_proto_family *ops)
{

 net_families[ops->family] = ops;

}

这里是sock创建时调用的函数

static int __sock_create(struct net *net, int family, int type, int protocol,
                         struct socket **res, int kern)
{

const struct net_proto_family *pf;
sock创建函数
pf = rcu_dereference(net_families[family]);

err = pf->create(net, sock, protocol);

err = security_socket_post_create(sock, family, type, protocol, kern);
//这里是启用了lsm的安全模块后的,这里不做为重点分析,以后再分析。

 *res = sock; 
}

下面就pf->create(net, sock, protocol);函数进行分析。分析内核如何创建socket。 pf所指向的create这个函数的真实实现是这里net/ipv4/af_inet.c中的这个函数: static int inet_create(struct net *net, struct socket *sock, int protocol)

在这个函数中创建并且根据用户请求sock的类型去初始化sock的相关操作。即初始化了sock->ops; 在以后的sock相关调用的时候就直接调用sock->ops->xxx函数了,比如sock->ops->bind, sock->ops->connect,sock->ops->listen,sock->ops->sendmsg,sock->ops->recvmsg, sock->ops->setsockopt。。。 而且还初始化了sock相关状态等信息。 而这里用于初始化sock->ops的数据结构是inetsw数组,这个数据是事先注册好的一个结构体数组。在后面会继续分析到。

看完本文有收获?请分享给更多人

关注「黑光技术」,关注大数据+微服务