![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux网络设备接口层
文章平均质量分 85
fanxiaoyu321
天道酬勤
展开
-
设备接口层初始化
这篇笔记分析了设备接口层的初始化代码实现,其中有些数据结构的详细情况会在后续相关的笔记中进一步说明。原创 2021-10-14 17:45:18 · 272 阅读 · 0 评论 -
net_device的分配与释放
这篇笔记分析了net_device的分配和释放流程。原创 2019-10-27 16:25:41 · 1058 阅读 · 0 评论 -
net_device的注册与注销
net_device对象只有通过register_netdev()注册到系统后才能被外部感知到。类似的,在释放之前需要通过unregister_netdev()将net_device对象先从系统中注销。这篇笔记分析了这两个过程的实现。原创 2018-11-13 00:30:42 · 4480 阅读 · 0 评论 -
net_device的管理
系统将所有已注册的网络设备从三个维度上组织为一个链表和两个哈希表:上面的三个表的表头是在网络命名空间中定义的,如下:表项定义每个网络设备也需要有相关的字段才能将网络设备对象接入全局的表中:组织结构清除了数据结构定义,下面来看看内核利用这些数据结构对已注册网络设备对象的组织:dev_base_head链表的内存布局如下所示:为了内存对齐,struct net_device结构在分配时有可能在其首部会有一段padding,而全局的dev_base_head指向的是net_device结构的第一个成员的原创 2018-11-11 12:59:27 · 1717 阅读 · 0 评论 -
实验: vcard虚拟网络设备生命周期
vcard介绍vcard是一个虚拟网卡,和具体的硬件无关,它没有任何的实际意义,但是通过编写这样一个虚拟网卡,我们可以很好的研究内核中网络设备层的代码逻辑。这篇笔记通过vcard虚拟网卡展示了网络设备的分配、注册、注销和销毁这一完整过程。网络设备的分配...原创 2019-10-27 16:58:28 · 357 阅读 · 0 评论 -
net_device的打开与关闭
前面的笔记分析了net_device的分配和注册流程,在可以进行数据收发之前,还需要打开net_device。对应的net_device不再工作时需要关闭net_device,这篇笔记来分析下这两个流程是如何实现的。原创 2019-11-03 12:35:56 · 1903 阅读 · 0 评论 -
设备接口层发送数据包
高层协议(如IP)经过路由后,为数据包确定了出口net_device,然后通过邻居子系统为数据包添加L2首部,最后数据包交给函数,由设备接口层接力后续的数据发送流程。这篇笔记分析了数据包从进入设备接口层到给到网络设备驱动之间的代码实现。原创 2018-11-17 13:59:51 · 1575 阅读 · 0 评论 -
实验:使用vcard发送数据包
这篇笔记使用AF_PACKET套接字实现向vcard发送数据包。原创 2019-11-23 11:12:41 · 242 阅读 · 0 评论 -
默认网络设备流量控制
在设备接口层之数据包发送中有介绍过,数据包发送分为有队列发送和无队列发送,并且有队列发送依赖于流量控制机制,这篇笔记就来看下流量控制相关的内容。流量控制机制的核心是为发送过程建立排队规则,让发送的每一包数据先入队列,然后再出队列,真正最终发送的顺序就是出队列的顺序,而是用什么样的队列,以及队列内部如何控制可以有上层通过tc工具进行配置,对于内核的发送框架,只规定了标准的入队和出队接口进行了标准化...原创 2018-11-18 17:21:04 · 1276 阅读 · 0 评论 -
设备接口层接收数据包(一)
数据包最先当然是由网卡收到(不考虑环回接口这样的虚拟设备),那么之后软件是如何接收该数据,又是如何将数据递交给协议栈的,这篇笔记就来看看linux内核和驱动程序时如何配合完整这个接收过程的。1. 数据接收模式当前内核提供了两种数据接收模式:非NAPI方式(老方法)和NAPI(新方法,即New API)。新老方法的接收过程分别如下图所示:1.1 非NAPI方式如上图b所示,当网卡收到数据包...原创 2018-11-14 22:29:39 · 2097 阅读 · 0 评论 -
设备接口层接收数据包(二)
这篇笔记和设备接口层之数据包接收中内容有重复,但是在之前的笔记中重点介绍的是网络设备如何和设备层的框架代码配合将数据包接收,对接收后数据包如何递交给上层协议只是简单的进行了介绍,这篇笔记会重点介绍下这方面的内容。此外,这篇笔记也会介绍下PF_PACKET套接字是如何在设备层进行勾包的。1. netif_receive_skb该函数详细说明还是见笔记“设备接口层之数据报接收”,这里我们将其中和...原创 2018-11-22 23:14:29 · 1186 阅读 · 0 评论 -
数据收发过程中的网络设备状态
从前面的数据收发过程中也看到了,在收发流程中很多检查设备状态的操作,这篇笔记来完整的看下在设备注册成功后,到底有哪些状态,它们是如何控制收发流程的。1. net_device的state字段dev->state字段描述了设备和设备队列的状态,当前定义有如下值:/* These flag bits are private to the generic network queueing ...原创 2018-11-18 13:07:10 · 5208 阅读 · 0 评论 -
实验: 非NAPI模式数据包接收方式
这篇笔记对vcard驱动进行改造,使其使用非NAPI模式和协议栈进行数据包的接收,以此来进一步加深对该模式的理解。核心思想使用定时器来模拟数据包的到来,这里假定每隔1s产生一个数据包;用户态使用AF_PACKET协议族套接字直接接收vcard网络设备上的数据包,以此来观察数据包接收情况;驱动核心代码用户态核心代码...原创 2019-11-01 21:23:17 · 328 阅读 · 0 评论 -
实验:NAPI模式数据包接收
和实验: 非NAPI模式数据包接收类似,这篇笔记使用vcard虚拟网卡来演示NAPI模式如何和协议栈配合完成数据包的接收,以便加深对这种接收模式的理解。核心思想vcard虚拟网卡使用NAPI模式和协议栈配合完成数据包接收;用户态使用AF_PACKET套接字编程接收来自vcard虚拟网卡的数据;内核态核心代码网络设备的定义需要包含struct napi_struct,所以不能再是简单的...原创 2019-11-02 23:41:21 · 448 阅读 · 0 评论 -
设备接口层NetPoll机制
文章目录数据结构NetPoll对象: netpollNetPoll信息: netpoll_info模块初始化: netpoll_init()注册NetPoll对象: netpoll_setup()发送数据: netpoll_send_udp()netpoll_send_skb()延时发送任务: queue_process()接收数据netpoll_poll()poll_napi()netpoll_rx()__netpoll_rx()NetPoll是设备接口层基于NAPI模式提供的一种纯粹的轮询接收数据包机原创 2021-10-20 15:38:22 · 981 阅读 · 0 评论 -
RFS特性
核心思想RPS的核心思想是将不同流的数据包映射到不同的CPU上进行接收,进而发挥多核的优势。数据包到达L4后会放入接收buffer中等待应用程序读取,如果能够更近一步,接收数据包的CPU和应用程序读取数据的CPU是同一个,那么就可以更好的提高cache命中率,进而能有更高的接收速率,这就是RFS补丁要做的事情。数据结构rps_sock_flow_table首先,引入了一个全局的哈希表来记录...原创 2020-01-04 11:59:43 · 1133 阅读 · 0 评论 -
RPS特性
数据结构RPS接收队列/* This structure contains an instance of an RX queue. */struct netdev_rx_queue { // 对应/sys/class/net/网卡/queues/rx-xxx/rps_cpus文件 struct rps_map *rps_map; struct kobject kobj; // 因为可...原创 2020-01-03 00:49:17 · 2123 阅读 · 0 评论 -
流量控制机制概述
文章目录数据结构qdiscqdisc句柄qdisc对象: Qdiscqdisc操作集: Qdisc_opsqdisc类操作集: Qdisc_class_ops注册qdisc: register_qdisc()classclass的IDclass哈希表: Qdisc_class_hashclass哈希表的分配和初始化: qdisc_class_hash_init()class公共信息: Qdisc_class_commonfilterfilter对象: tcf_protofilter操作集: tcf_prot原创 2021-11-06 13:32:56 · 1781 阅读 · 0 评论 -
流量控制Netlink接口
netlink消息接口注册显然,netlink接口应该支持流量控制中三个组件的增加、删除和查询操作。对排队规则、类的接口注册在pktsched_init()中完成;对过滤器的接口的注册在tc_filter_init()中完成。static int __init pktsched_init(void){ // 注册pfifo和bfifo两种排队规则 register_qdisc(&...原创 2019-11-08 01:13:56 · 824 阅读 · 0 评论 -
无类流控qdisc之bfifo和pfifo
这篇笔记分析了内置的bfifo排队规则的实现。排队规则的注册在流量控制机制的初始化过程中,就向内核注册了pfifo和biffo两个排队规则。static int __init pktsched_init(void){ register_qdisc(&pfifo_qdisc_ops); register_qdisc(&bfifo_qdisc_ops);... retu...原创 2019-11-14 00:39:56 · 634 阅读 · 0 评论 -
无类流控qdisc之tbf
这篇笔记记录无类排队规则TBF的内核代码实现。/* Simple Token Bucket Filter. ======================================= SOURCE. ------- None. Description. ------------ A data flow obeys TBF with rate R and depth B,...原创 2019-11-22 00:26:36 · 1519 阅读 · 1 评论 -
分类流控qdisc之htb
文章目录tc参数配置示例算法思想用户态实现数据结构htb全局配置参数: tc_htb_globhtb类配置参数: tc_htb_optqdisc配置参数解析: htb_parse_opt()class配置参数解析: htb_parse_copt()内核实现数据结构qdisc操作集私有数据: htb_schedhtb类结构: htb_classqdisc操作集: htb_qdisc_ops初始化: htb_init()qdisc类操作集: htb_class_opschange()回调: htb_change原创 2021-11-06 13:36:49 · 1816 阅读 · 0 评论 -
u32过滤器
文章目录命令行说明示例数据结构match参数: tc_u32_key/tc_u32_sel命令行参数解析: u32_parse_opt()内核态实现数据结构tc_u_commonfilter对象: tc_u_hnodematch信息: tc_u_knodeu32 filter操作集: cls_u32_ops初始化: u32_init()获取filter对象/match对象: u32_get()修改参数: u32_change()分类: u32_classify()u32是最通用的一个数据包filter,它原创 2021-11-06 13:37:42 · 1592 阅读 · 0 评论 -
入口流量控制
文章目录handle_ing()入口数据包过滤: ing_filter()接收方向qdisc: ingress_qdiscingress_qdisc私有数据结构: ingress_qdisc_data入队: ingress_enqueue()在驱动将数据包递交给协议栈的最后一步netif_receive_skb()函数中,有这个宏CONFIG_NET_CLS_ACT控制的相关逻辑是入口流量控制。handle_ing()static inline struct sk_buff *handle_ing(s原创 2021-11-06 13:38:24 · 382 阅读 · 0 评论 -
网络设备: net_device
在linux内核中,struct net_device是对一张网卡的定义,该网卡可能是物理网卡,也可能是虚拟网卡,甚至是对多张物理网卡的组合的抽象。下面是该结构的定义,其定义相当的复杂,其中有很多是特性相关的成员,可以暂时不关注。/* * The DEVICE structure. * Actually, this whole structure is a big mistake. It ...原创 2019-10-27 00:53:14 · 3190 阅读 · 0 评论