代码取自2.6.18.8.
Socket_register(协议套接字注册) 1. 各协议族通过该接口进行注册, 这里只需要分析常见的几种类型:IPv4/IPv6/Netlink/Packet/unix
2. 最多支持32个协议族
3. 使用全局数组net_families保存协议族的注册信息,包括类型和创建函数
Netlink用户态:创建socket套接字,socketfd = socket (AF_NETLINK, SOCK_RAW, PRIV_ID);
内核态:sys_socket
- 调用sock_create创建socket
1. 调用sock_alloc,申请socket。
2. sock_alloc调用new_inode申请inode节点并初始化,通过SOCKET_I获取socket
3. 调用注册的协议族类型的创建函数,完成初始化相关动作 - 调用sock_map_fd将socket与虚拟文件系统绑定
其中netlink的协议族注册是在net/netlink/af_netlink.c中完成的, af_netlink协议初始化如下
netlink_proto_init
1. 调用proto_register, 将netlink_proto结构挂接到系统的网络协议链表中
2. 分配MAX_LINKS个netlink表结构, nl_table, 每个成员代表一种协议类型
3. 然后为nl_table中每种协议类型分配一个hash表的链头, 并进行初始化
4. 调用sock_register注册netlink协议族的操作结构. 这样就可以使用其注册的接口完成socket中的初始化动作了
5. 调用rtnetlink_init完成路由netlink的初始化用户态: 套接字绑定, bind(socket_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)
内核态: sys_bind
- 对于 AF_INET 协议簇来讲,其地址格式是 strut sockaddr_in,对AF_NETLINK协议族而言, 其地址格式为
struct sockaddr_nl, 而对于 socket 来讲,strut sockaddr 结构表示的地址格式实现了更高层次 的抽像,
因为每种协议簇的地址不一定是相同的,所以,系统调用的第三个参数得指明该协议簇的地址格式的长度。 - sys_bind入参包括套接字描述符, 地址, 和地址长度, 首先要根据socket_fd找到对应的struct socket *sock
结构信息
阅读(3968) | 评论(0) | 转发(3) |