最近要给团队做一个长期的内部分享,主题就是Linux内核中数据包的处理流程。 这几天抽空画了一部分流程图。...我本人对网卡驱动兴趣不大,但skb path又无法脱离网卡驱动,这里选择了Intel的e1000网卡驱动:原因有二,一是Intel网卡驱动是内核里面写得最清楚,可读性最高的;二是e1000是Intel里面比较简单的驱动
代码demo.c #include #include #include #include #include #include #include #include #include #include #include #include...priv->stats.rx_dropped++; return; } skb_reserve(skb, 2); memcpy(skb_put(skb, len), buf..., len); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); // 不需要检查checksum skb-
现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...但是,即便Linux内核协议栈收包效率真的很低,这是为什么?有没有办法去尝试着优化?而不是动不动就DPDK。 我们从最开始说起。...Linux内核并没有在横向上将锁的粒度做划分,而是在纵向上,采用两个层次的锁机制: 我们看到的Linux内核在处理收包逻辑时的backlog,其实抽象出来就是上面的二级锁,它是不是很像Windows的...事实上这是一种非常常见且通用的设计,除了Windows的IRQL,Linux中断的上半部/下半部也是这种基于思想设计的。...当然,Linux内核协议栈无法摆脱这两点问题,也就回答了本文的题目中的第一个问题, “Linux内核UDP收包为什么效率低?” 。 不同的上下文异步操作同一份数据,锁是必不可少的。
/module.h> #include #include #include #include... #include #include #include #include... #include #include #include #include #include #include #include #include len), skb->data, skb->len); // skb_put():来动态扩大sk_buff结构体里中的数据区,避免溢出 /*8)设置新的
将多个TCP分段聚合成一个skb结构,以减小上层协议栈的skb的开销。skb的数据保存在skb->data中,分段的数据保存在skb_shared_info->frag_list中。...所以GSO本身是对UFO的优化);如果硬件不支持,则在进入device driver queue之前由linux内核调用UDP GSO分片函数,然后再一直往下到网卡。...segs) return 0; skb->next = segs; DEV_GSO_CB(skb)->destructor = skb->destructor; skb->destructor...2, 即使br-ex不是linux bridge,eth0在重组后做完防火墙后再使用9000再重新分片, 再传到后面1500的虚拟设备又会重组。...VMware STT隧道 如果现在不是Linux + OVS bridge (ovs bridge支持STT,Linux Bridge不支持STT) + virtio, 而是VMware STT呢?
基本介绍 第三类是标准的网络接口Linux设备,本章介绍的内核,其余的交互网络接口描述 网络接口,必须使用特定的内核数据结构本身注册,与外部分组交换数据线打电话时准备 经常使用的文件上的网络接口操作是没有意义的...>) FDDI设备使用alloc_fddidev() 令牌环设备使用alloc_trdev() register_netdev...该结构定义在中 传递经全hard_start_xmit的套接字缓冲区包括了物理数据包,并拥有完整的传输层数据包头 该传输函数仅仅运行了对数据包的一致性检查。...dev_kfree_skb_any(struct sk_buff *skb); 不使用接收中断 为了能提高Linux在宽带系统上的性能。...sk_buff *skb); void dev_kfree_skb(struct sk_buff *skb); void dev_kfree_skb_irq(struct sk_buff *skb);
本文作者张彦飞,原题“图解Linux网络包接收过程”,内容有少许改动。...相信这对你的工作将会有非常大的帮助(本文将以Linux为例,源码基于Linux 3.10,源代码参见:https://mirrors.edge.kernel.org/pub/linux/kernel/v3...对于Linux来说,它实现的是链路层、网络层和传输层这三层。 在Linux内核实现中,链路层协议靠网卡驱动来实现,内核协议栈来实现网络层和传输层。...我们用Linux的视角来看到的TCP/IP网络分层模型应该是下面这个样子的: 在Linux的源代码中,网络设备驱动对应的逻辑位于driver/net/ethernet。...Linux内核网络收包总览: 如上图所示:当网卡上收到数据以后,Linux中第一个工作的模块是网络驱动。网络驱动会以DMA的方式把网卡上收到的帧写到内存里。
所以,当网卡接收到数据包后,要通知 Linux 内核有数据需要处理。另外,网卡驱动应该提供让 Linux 内核把数据把发送出去的接口。...net_device 结构是 Linux 为了适配不同类型的网卡设备而抽象出来的对象,不同的网卡驱动只需要按 Linux 的规范来填充 net_device 结构的各个成员变量,Linux 内核就能够识别出网卡...net_device 结构 net_device 结构是 Linux 内核对网卡设备的抽象,但由于历史原因,net_device 结构的定义十分复杂。...当网卡从网络接收到数据包后,需要产生一个中断来通知 Linux 内核有数据包需要处理,而 irq 就是网卡驱动注册到内核中断服务的中断号。...= dev_alloc_skb(pkt_len + 2); // 申请一个数据包对象 if (skb) { skb_reserve(skb, 2
1.3 安装对应版本的linux内核镜像 (1)目标机上安装对应版本的linux内核镜像 下载地址:http://security.ubuntu.com/ubuntu/pool/main/l/linux.../ (2)客户机上安装对应版本的带有符号表的linux内核镜像 下载地址:http://ddebs.ubuntu.com/pool/main/l/linux/,并且源码下载,建立软链接使得调试的时候能够跟踪源码...减少Linux 内核传输层和网络层的计算工作,将这些计算工作offload(卸载)到物理网卡。UDP协议层本身不对大的数据报进行分片,而是交给IP层去做。...六 影响版本 http://www.securityfocus.com/bid/100262 影响linux kernel 4.12.3之前的版本,在4.14的版本将移除UFO机制。...七 参考资料 Linux 内核源码剖析- TCP.IP 实现, 樊东东, 莫澜, 上册, 2011 A Guide to Kernel Exploitation Attacking the Core http
在 上一篇文章 中,我们介绍了网卡接收和发过数据在 Linux 内核中的处理过程,我们先来回顾一下网卡接收和发送数据的过程,如 图1 所示: ?...为了避免这种情况出现,Linux 内核把中断处理分为:中断上半部 和 中断下半部,上半部在关闭中断的情况下进行,而下半部在打开中断的情况下进行。...NET_RX_DROP; } netif_rx 函数的参数就是要上送给网络协议栈的数据包,netif_rx 函数主要完成以下几个工作: 获取当前 CPU 的待处理的数据包队列,在 Linux 内核初始化时...对于 Linux 内核的中断处理机制可以参考我们之前的文章 Linux中断处理,这里就不详细介绍了。在本文中,我们只需要知道网络中断下半部处理例程为 net_rx_action 函数即可。...for (;;) { struct sk_buff *skb; local_irq_disable(); skb = __skb_dequeue
在这三个参数中,我们主要来将视线放在 struct sk_buff *skb 上。 熟悉 Linux Kernel 协议栈实现的同学肯定对 sk_buff 这个数据结构非常非常熟悉了。...实际上我们现在有很多 Centos 7 + Linux 3.10 这样的传统的搭配,那么他们怎么办呢? Linux 3.10 live's matter!.../if_ether.h> #include #include #include #include...#include #include #include #include %} function.../ptrace.h> #include #include #include #include <net/
Linux 内核网络栈是一个纯内核态的东西,和用户层功能是天然隔离。但为了迎合各种各样用户层不同的需求,内核开放了一些口子出来供用户干预。...Linux 在内核网络组件中很多关键位置布置了 netfilter 过滤器。Iptables 就是基于 netfilter 来实现的。...其实除了接收和发送过程以外,Linux 内核还可以像路由器一样来工作。...3.1 nat 假如说我们有一台 Linux,它的 eth0 的 IP 是10.162.0.100,通过这个 IP 可以访问另外其它服务器。...Linux 上的防火墙、nat 等基础功能都是基于它实现的。还有现如今流行的的 Docker、Kubernets、Istio 项目中也经常能见着对它的身影。
而很多时候,如果你对Linux底层的理解不深的话,遇到很多线上性能瓶颈你会觉得狗拿刺猬,无从下手。 我们今天用图解的方式,来深度理解一下在Linux下网络包的接收过程。...本文基于Linux 3.10,源代码参见https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/,网卡驱动采用Intel的igb网卡举例。...Linux实现的是链路层、网络层和传输层这三层。 在Linux内核实现中,链路层协议靠网卡驱动来实现,内核协议栈来实现网络层和传输层。内核对更上层的应用层提供socket接口来供用户进程访问。...二 Linux启动 Linux驱动,内核协议栈等等模块在具备接收网卡数据包之前,要做很多的准备工作才行。...这块相对比较简单,剩下大部分的戏份都是由Linux内核其它模块来表演了。 首先在开始收包之前,Linux要做许多的准备工作: 1.
前言 Linux内核网络 UDP 协议层通过调用 ip_send_skb 将 skb 交给 IP 协议层,本文通过分析内核 IP 协议层的关键函数来分享内核数据包发送在 IP 协议层的处理,并分享了监控...3.2 目的(路由)缓存 dst 代码在 Linux 内核中实现协议无关的目标缓存。...以上两种情况,最后都会到 dev_queue_xmit,它将 skb 发送给 Linux 网络设备子系统,在它 进入设备驱动程序层之前将对其进行更多处理。...将头数据复制到 skb 后,skb_push 将更新 skb 内指向数据缓冲区的指针。最后调用 dev_queue_xmit 将 skb 传递给 Linux 网络设备子系统。...else goto out_kfree_skb; } 如果以太网头写入成功,将调用 dev_queue_xmit 将 skb 传递给 Linux
Linux 网络架构 Linux 网络初始化 网络设备子系统初始化 网卡驱动初始化 协议栈初始化 数据包的接收过程 硬中断处理 ksoftirqd 软中断处理 协议栈处理 应用层处理 总结 这里深度理解一下在...Linux 网络架构 在Linux内核实现中,链路层协议靠网卡驱动来实现,内核协议栈来实现网络层和传输层。内核对更上层的应用层提供socket接口来供用户进程访问。...我们用Linux的视角来看到的TCP/IP网络分层模型应该是下面这个样子的。...Linux 网络初始化 网络设备子系统初始化 linux内核通过调用subsys_initcall来初始化各个子系统,其中网络子系统的初始化会执行到net_dev_init函数: //net/core/...总结 首先在开始收包之前,Linux要做许多的准备工作: 创建ksoftirqd线程,为它设置好它自己的线程函数,后面指望着它来处理软中断呢 协议栈注册,linux要实现许多协议,比如arp,icmp,
现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...但是,即便Linux内核协议栈收包效率真的很低,这是为什么?有没有办法去尝试着优化?而不是动不动就DPDK。 我们从最开始说起。...Linux内核并没有在横向上将锁的粒度做划分,而是在纵向上,采用两个层次的锁机制: ?...事实上这是一种非常常见且通用的设计,除了Windows的IRQL,Linux中断的上半部/下半部也是这种基于思想设计的。...当然,Linux内核协议栈无法摆脱这两点问题,也就回答了本文的题目中的第一个问题, “Linux内核UDP收包为什么效率低?” 。 不同的上下文异步操作同一份数据,锁是必不可少的。
2.2 VxLAN的创建和数据的监听和处理 首先介绍下linux内核中sock和socket还有skb。...socket主要作用于Linux系统中的BSD层(L6层),INET层很少应用, BSD和INET层分别对应ISO中的表示层和会话层,其结构体相对sock而言比较简单;而sock贯穿了硬件层和设备接口层和...内核工作队列需要用到的结构体, 该结构体定义了新启线程需要完成的工作的抽象 struct socket *sock; struct rcu_head rcu; //linux线程锁...一个很重要的点是:在linux内核中,无论收发数据,都会被缓存到sock 结构中的缓冲队列中。...tos, ttl, df, false); } linux内核中vxlan_xmit_skb函数的功能是对skb进行vxlan封装,在OVS中对该函数进行了重写,增加了NSH封装功能。
本文将介绍在Linux系统中,以一个UDP包的接收过程作为示例,介绍数据包是如何一步一步从应用程序到网卡并最终发送出去的。 socket层 socket(...)...构造skb结构体,最后将网卡的信息和该skb关联。...从sendto函数的帮助文件里面看到这样一句话:(Normally, this does not occur in Linux....这里的device queue应该指的是Traffic Control里面的queue,说明在linux里面,默认的SO_SNDBUF值已经够queue用了,疑问的地方是,queue的长度和个数是可以配置的...txqueuelen: 很多地方都说这个是控制qdisc里queue的长度的,但貌似只是部分类型的qdisc用了该配置,如linux默认的pfifo_fast。
系统环境: # uname -r 3.10.0-1160.99.1.el7.x86_64 # cat /etc/centos-release CentOS Linux release 7.6.1810...void *location; unsigned short protocol; }; SEC("tracepoint/skb/kfree_skb") int tp_kfree_skb...GEN-SKEL trace_kfree_skb.skel.h CC trace_kfree_skb.o BINARY trace_kfree_skb # ls trace_kfree_skb...验证在centos7 3.10内核正常运行ebpf程序 # uname -r 3.10.0-1160.99.1.el7.x86_64 # cat /etc/centos-release CentOS Linux.../skb/kfree_skb, size 88, link 0, flags 6, type=1 libbpf: sec 'tracepoint/skb/kfree_skb': found program
前言我们可以使用BPF对Linux内核进行跟踪,收集我们想要的内核数据,从而对Linux中的程序进行分析和调试。...与其它的跟踪技术相比,使用BPF的主要优点是几乎可以访问Linux内核和应用程序的任何信息,同时,BPF对系统性能影响很小,执行效率很高,而且开发人员不需要因为收集数据而修改程序。...print_functionfrom bcc import BPFfrom time import sleep# define BPF programbpf_program = """#include <uapi/linux...;fn_name="trace_kfree_skb"指定了当内核函数kfree_skb有返回值时,执行程序中的trace_kfree_skb函数;4....命名约定,首先是指定要跟踪的子系统,这里是“skb:”,然后是子系统中的跟踪点“kfree_skb”:图片5.
领取专属 10元无门槛券
手把手带您无忧上云