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

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数组,这个数据是事先注册好的一个结构体数组。在后面会继续分析到。

Leave a Reply

Your email address will not be published. Required fields are marked *