protocol链表数组
inet有些例外,因为inet支持的类型太过复杂(maybe), 所以引入了一个inetsw的链表数组。
就像注释里说的一样。inetsw是inet socket创建的基础,包含创建inet socket全部的所需要信息。
inetsw
1 | 125 /* The inetsw table contains everything that inet_create needs to |
inetsw
是一个链表头的数据,每个链表是具有相同的type的, 具体见socket type.
每个节点是一个struct inet_protosw
. 每个节点是通过net_register_protosw
插入到其type对应的链表里的。
struct inet_protosw
1 | 78 /* This is used to register socket interfaces for IP protocols. */ |
两个重要的指针
每种socket都有其对应的struct proto_ops *ops
,该指针会存放在struct socket
里。
inet的socket在创建的时候会指定两个函数指针:
struct proto_ops *ops
该指针被存放到struct socket
里.
一般socket这些函数就是真正的bind, connect,sendmsg函数。
但是在inet里,这些函数其实是通用的或者基于某个type(如stream)的操作。
如inet_bind
,inet_sendmsg
inet_stream_connect
等。struct proto *prot
该指针被存放到struct sock
里.
各个协议自己的特殊处理,被抽象并整理到这里,如tcp_v4_connect
.
struct proto_ops *ops
经常使用’sk->sk_prot->XXX调用响应的proto处理函数。 如:
inet_stream_connect/__inet_stream_connect调用`sk->sk_prot->connect
一个具体的例子
如tcp协议的struct proto_ops *ops
是inet_stream_ops
, struct proto *prot
是tcp_prot
1 | 997 { |
两个指针何时被初始化的
上述两个指针在sock创建时候就被确定下来了.
函数inet_create
会根据socket系统调用指定的type,proto参数,去inetsw链表里查找。
并将找到的节点里的struct proto_ops *ops
和struct proto *prot
分别保存到该socket对应的socket
和sock
里。
几点说明 struct inet_protosw
- permanent protocol
因为struct inet_protosw
有永久(permanent)和临时之分。
所为permanent节点就是其结构体的flag带有INET_PROTOSW_PERMANENT
标志位。说明其对应的协议不允许被override.
而临时节点则相反,没有INET_PROTOSW_PERMANENT
标志,新插入的协议override原有的。
所有永久的节点被放在了链表的头部,而新插入的临时节点
都会被放到permanent节点的后面。
1 | 1030 |
1 | 58 enum sock_type { |