在 上一篇文章 中,我们介绍了网卡接收和发过数据在 Linux 内核中的处理过程,我们先来回顾一下网卡接收和发送数据的过程,如 图1 所示: ?...函数的参数就是要上送给网络协议栈的数据包,netif_rx 函数主要完成以下几个工作: 获取当前 CPU 的待处理的数据包队列,在 Linux 内核初始化时,会为每个 CPU 创建一个待处理数据包队列...netif_rx 函数的处理过程如 图2 所示: ?...图2 netif_rx 函数的处理过程 所以,netif_rx 函数的主要工作就是把接收到的数据包添加到待处理队列中,并且启动网络中断下半部处理。...对于 Linux 内核的中断处理机制可以参考我们之前的文章 Linux中断处理,这里就不详细介绍了。在本文中,我们只需要知道网络中断下半部处理例程为 net_rx_action 函数即可。
( )来将sk_fuffer传递给上层协议中 7.驱动具体代码如下: #include linux/module.h> #include linux/errno.h> #include linux.../netdevice.h> #include linux/etherdevice.h> #include linux/kernel.h> #include linux/types.h> #include...linux/fcntl.h> #include linux/interrupt.h> #include linux/ioport.h> #include linux/in.h> #include...linux/skbuff.h> #include linux/slab.h> #include linux/spinlock.h> #include linux/string.h> #include...linux/init.h> #include linux/bitops.h> #include linux/delay.h> #include linux/ip.h> #include <
我们拆解完了 Linux 网络包的接收过程,也搞定了网络包的发送过程。内核收发网络包整体流程就算是摸清楚了。...1.2 跨机数据接收 当数据包到达另外一台机器的时候,Linux 数据包的接收过程开始了。 当网卡收到数据以后,CPU发起一个中断,以通知 CPU 有数据到达。...我们在 Linux 上使用命令名可以查看到这两个路由表, 这里只看 local 路由表(因为本机网络 IO 查询到这个表就终止了)。...if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { } } 在 skb_orphan 中先是把 skb 上的 socket 指针去掉了(剥离了出来)。...接着调用 netif_rx,在该方法中 中最终会执行到 enqueue_to_backlog 中(netif_rx -> netif_rx_internal -> enqueue_to_backlog)
所以,当网卡接收到数据包后,要通知 Linux 内核有数据需要处理。另外,网卡驱动应该提供让 Linux 内核把数据把发送出去的接口。...net_device 结构是 Linux 为了适配不同类型的网卡设备而抽象出来的对象,不同的网卡驱动只需要按 Linux 的规范来填充 net_device 结构的各个成员变量,Linux 内核就能够识别出网卡...当网卡从网络接收到数据包后,需要产生一个中断来通知 Linux 内核有数据包需要处理,而 irq 就是网卡驱动注册到内核中断服务的中断号。...)); skb->protocol = eth_type_trans(skb, dev); // 从以太网头部中获取网络层协议类型 netif_rx...调用 netif_rx 函数将数据包上送给内核网络协议栈。 当把数据包上送给内核网络协议栈后,数据包的处理就由内核接管。
信息量大,console(如果有)有大量的打印输出,用户无法在console输入命令,影响人机交互 内核解决方案 内核采用“插桩”的方法抓取log,“插桩”也称为Tracepoint,Tracepoint是Linux.../tracepoint.h struct tracepoint include/linux/tracepoint-defs.h Tracepoint依次执行桩函数,每个桩函数实现不同的debug功能。...(例如,includelinux/sched.h>)。...tracepoint.h文件是必需的 #include linux/tracepoint.h> 现在可以使用trace_EVENT()宏定义所有跟踪事件。.../init.h> #include linux/module.h> #include linux/kthread.h> #define CREATE_TRACE_POINTS #include "
3.2 跨机数据接收 当数据包到达另外一台机器的时候,Linux 数据包的接收过程开始了(更详细的讲解可以看看《深入操作系统,从内核理解网络包的接收过程(Linux篇)》)。...我们在 Linux 上使用命令名可以查看到这两个路由表, 这里只看 local 路由表(因为本机网络 IO 查询到这个表就终止了)。...loopback_xmit(struct sk_buff *skb, struct net_device *dev) { //剥离掉和原 socket 的联系 skb_orphan(skb); //调用netif_rx... if(likely(netif_rx(skb) == NET_RX_SUCCESS)) { } } 在 skb_orphan 中先是把 skb 上的 socket 指针去掉了(剥离了出来)。...接着调用 netif_rx,在该方法中 中最终会执行到 enqueue_to_backlog 中(netif_rx -> netif_rx_internal -> enqueue_to_backlog)
代码demo.c #include linux/module.h>#include linux/init.h>#include linux/moduleparam.h>#include linux.../module.h>#include linux/kernel.h>#include linux/slab.h> #include linux/fs.h>#include linux/errno.h...linux/version.h>#include linux/vmalloc.h>#include linux/delay.h>#include linux/ctype.h>#include..."Dual BSD/GPL"); static char netbuffer[100];struct net_device *net_devs; // 接收网络数据包并将数据包放入TCP/IP上层 netif_rx...skb->ip_summed = CHECKSUM_UNNECESSARY; priv->stats.rx_packets++; netif_rx
linux内核为了高性能,很喜欢用rwlock的改进版rcu,这种思想是值得借鉴的。 ...switch (rx_handler(&skb)) // 交给rx_handler处理,例如ovs, linux bridge等 此类接口处理报文在协议栈之前,因此netfilter对此类接口不起作用,...所以在云环境(openstack)中,需要在虚拟机tap口与虚拟交换机之间增加Linux bridge设备来使报文经过协议栈(netfilter起作用)来实现security group。.../*skb处理完成,进入主要函数*/ netif_rx(skb); } 这里有点绕:前面有讲在包递交到协议栈之前,ovs有截获。...而这里netif_rx又是走的本机协议栈处理,到底走哪个?
veth_xdp_rx(rq, skb) : netif_rx(skb);//中断处理 } /* Called with irq disabled */ static inline void...NET_RX_SOFTIRQ); } 通过虚拟的veth发送数据和真实的物理接口没有区别,都需要完整的走一遍内核协议栈,从代码分析调用链路为veth_xmit -> veth_forward_skb -> netif_rx...4.1 ipvlan L2 模式 IPvlan和传统Linux网桥隔离的技术方案有些区别,它直接使用linux以太网的接口或子接口相关联,这样使得整个发送路径变短,并且没有软中断的影响,从而性能更优。
本文将介绍在Linux系统中,以一个UDP包的接收过程作为示例,介绍数据包是如何一步一步从网卡传到进程手中的。 网卡到内存 网络接口卡必须安装与之匹配的驱动程序才能正常工作。...enqueue_to_backlog函数也会被netif_rx函数调用,而netif_rx正是lo设备发送数据包时调用的函数 协议栈 IP层 由于是UDP包,所以第一步会进入IP层,然后一级一级的函数往下调...在Linux中,每个socket都可以像tcpdump中一样定义过滤条件,不满足条件的数据包将被丢弃。 __skb_queue_tail函数用于将数据包放入socket的接收队列末尾。
虽然我自认为把原生 Linux 网络实现过程理解的还算不错了。但在看网络虚拟化相关的技术的时候,还是觉得不是很容易。 不过,飞哥有绝招,那就是先挑个软柿子来捏。...在 Linux 下,我们可以通过使用 ip 命令创建一对儿 veth。其中 link 表示 link layer的意思,即链路层。...网络包发送过程》和《图解Linux网络包接收过程》两篇文章中,我们系统介绍了 Linux 网络包的收发过程。...return netif_rx(skb); } 先调用了 eth_type_trans 将 skb 的所属设备改为了刚刚取到的 veth 的对端设备 rcv。...在该方法中最终会执行到 enqueue_to_backlog 中(netif_rx -> netif_rx_internal -> enqueue_to_backlog)。
本篇简单分析Linux(2.6.32版本)中的IPIP隧道的实现过程,期望有所借鉴,造出轮子:-) 一....IPIP的初始化 Linux中的IPIP隧道文件主要分布在tunnel4.c和ipip.c文件中。...因为是三层隧道,在IP报文中填充的三层协议自然就不能是常见的TCP和UDP,所以,Linux抽象了一个隧道层,位置就相当于传输层,主要的实现就是在tunnel4.c中。...secpath_reset(skb); skb->mac_header = skb->network_header; /* 修改报文的mac头指向网络层开始,为了下面使用netif_rx...skb_dst_drop(skb); nf_reset(skb); ipip_ecn_decapsulate(iph, skb); netif_rx
. */ // 读取数据到skb中 insb(DATAPORT, skb->data, pkt_len); // 传给mac层 netif_rx(skb);...lp->stats.rx_packets++; } return; } 驱动层处理生成一个skb结构体,然后通过netif_rx函数传给链路层。...netif_rx直接把skb挂载到backlog队列中,然后结束中断处理,等下半部分再进行数据包的具体处理。由sock_init函数的代码我们知道,下半部分的处理函数是net_bh。...This is the recommended * interface to use. */ void netif_rx(struct sk_buff *skb) { static
Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计。 Linux内核采用分层结构处理网络数据包。...在Linux内核,所有的网络设备都被抽象为一个接口处理,该接口提供了所有的网络操作。 net_device结构表示网络设备在内核中的情况,也就是网络设备接口。...Linux内核有一个dev_base的全局指针,指向一个设备链表,包括了系统内的所有网络设备。该设备链表每个节点是一个网络设备。 ...net_device结构保存在include/linux/netdevices.h头文件,理解该结构对理解网络设备驱动有很大帮助。 ...dm9000_rx()函数收到数据包完成后,内核会继续调用 netif_rx()函数,函数的作用是把网卡接收到数据提交给协议栈处理。
基本介绍 第三类是标准的网络接口Linux设备,本章介绍的内核,其余的交互网络接口描述 网络接口,必须使用特定的内核数据结构本身注册,与外部分组交换数据线打电话时准备 经常使用的文件上的网络接口操作是没有意义的...>) FDDI设备使用alloc_fddidev(linux/fddidevice.h>) 令牌环设备使用alloc_trdev(linux/trdevice.h>) register_netdev...该结构定义在linux/skbuff.h>中 传递经全hard_start_xmit的套接字缓冲区包括了物理数据包,并拥有完整的传输层数据包头 该传输函数仅仅运行了对数据包的一致性检查。...驱动程序更新其统计计数器 接收数据包过程中的最后一个步骤由netif_rx运行 中断处理例程 接口在两种可能的事件下中断处理器 新数据包到达 外发数据包的传输已经完毕 通常中断例程通过检查物理设备中的状态寄存器...从如今開始启动轮询接口 用netif_receive_skb函数将数据包传递给内核,而不是使用netif_rx 调用netif_rx_complete关闭轮询函数 链路状态的改变 大多数涉及实际的物理连接的网络技术提供载波状态信息
} 5.3 通过netif_rx函数上报数据代码编写示例 /* 工作队列处理函数 以下函数用于读取网卡里的数据。...#include linux/init.h> #include linux/module.h> #include linux/netdevice.h> #include linux/etherdevice.h.../init.h> #include linux/module.h> #include linux/netdevice.h> #include linux/etherdevice.h> #include.../gpio-cfg.h> #include linux/delay.h> #include linux/workqueue.h> #include linux/delay.h> #include...linux/interrupt.h> #include linux/irq.h> #include linux/timer.h> /* 参考的网卡程序: cs89x0.c与Enc28j60
* 在linux主机上输入"ifconfig" 看见eth 和 lo。...lb_stats = this_cpu_ptr(dev->lstats); //获取数据包的长度 len = skb->len; /*判断数据包是否接受成功*/ if (likely(netif_rx
PF_RING的工作流程: 普通的网络接收函数中,网卡驱动到内核传递数据的核心是netif_rx()函数,若使用了设备轮询(NAPI)机制(中断机制+轮询机制,以中断方式通知系统,将设备注册到轮询队列后关闭中断
所以,Linux 内核提供了 虚拟网络设备对(veth) 这个功能,用于解决不同网络命名空间之间的通信。...当然,本文的主题是 veth 的实现,而不是 网桥 的现实,所以对 网桥 的介绍就此结束,有兴趣可以参考《Linux网桥工作原理与实现》一文。...虚拟网络设备对实现 在 Linux 内核中,使用 net_device 对象来表示一个网络设备。由于 veth 提供双向通信的功能,所以需要使用两个 net_device 对象来实现。...虽然 Linux 内核使用 net_device 对象来表示一个网络设备,但由于不同厂商的网络设备可能存在各种差异,所以为了让 Linux 内核能够适应各种网络设备,故为不同的网络设备提供私有数据的存储空间...// 将数据包的接收设备设置为对端设备 skb->protocol = eth_type_trans(skb, rcv); ... // 将数据包上送给内核协议栈 netif_rx
Linux 文件系统 目录 说明 bin 存放二进制可执行文件 sbin 存放二进制可执行文件,只有 root 才能访问 boot 存放用于系统引导时使用的各种文件 dev 用于存放设备文件 etc...是超级管理员 localhost 表示主机名 ~ 表示当前目录(家目录),其中超级管理员家目录为 /root,普通用户家目录为 /home/chan $ 表示普通用户提示符,# 表示超级管理员提示符 Linux...test.tar.gz 文件搜索命令 locate:在后台数据库搜索文件 updatedb:更新后台数据库 whereis:搜索系统命令所在位置 which:搜索命令所在路径及别名 find:搜索文件或文件夹 用户和组 Linux
领取专属 10元无门槛券
手把手带您无忧上云