Linux内核代码笔记6----网络模型

linux网络协议栈分析笔记10-arp邻居子系统3 还是回到neigh_resolve_output() int neigh_resolve_output(struct sk_buff *skb) {      struct dst_entry *dst = skb_dst(skb);      struct neighbour *neigh;      int rc = 0;      if (!dst || !(neigh = 阅读详情
网络协议
TCP/IP模型
  • 应用层 (TELNET、FTP、DNS)
  • 传输层(TCP、UDP)
  • Internet(IP)
  • 网络接口物理层(PPP/SLIP、LAN)
Internet协议
    IP定义了一个协议,而不是一个连接。IP主要负责数据报在计算机之间的寻址问题,并管理这些数据报的分段过程。传输具有“不可靠性”,验证和流量控制交给其他层完成。IP是无连接的。
    面向连接:通信双方在通信时,事先建立一条通信线路。过程有建立连接、使用连接、释放连接等;
    无连接:   通信双方事先不需要建立通信线路,而是把带有目的的地址的包送到线路上,由系统选定路线。

TCP协议
    TCP可以向上层提供面向连接的协议,使上层启动应用程序。作用是提供可靠通信的有效报文协议。

套接字
    Linux支持多种套接字种类,不同的套接字种类称为“地址族”。Linux将上述套接字地址族抽象为统一的BSD套接字接口,比如stream、datagram、raw等。

网络设备接口
    网络设备结构:


    网络设备驱动程序功能:
  • 发送数据
        驱动将来自协议层的网络缓冲区通过hard_start_xmit()发送到物理介质,并接收硬件产生的应答信号。
        dev->hard_start_xmit():将网络缓冲区,也就是sk_buff 发送到硬件设备。如果设备不能接受缓冲区,它就会返回1。如果协议层决定释放被设备抛弃的缓冲区,那么缓冲区就不会再被送回设备;如果设备知道缓冲区短时间内不被能传送,例如设备严重堵塞,那么它就调用  dev_kfree_skb()函数丢掉缓冲区,该函数返回零值标明缓冲区已经被处理完毕。

        当缓冲区被传送到硬件以后,硬件应答信号标识传输已经完毕,驱动程序必须调用dev_kfree_skb(skb, FREE_WRITE)函数释放缓冲区,一旦该调用结束,缓冲区就会很自然地消失,这样,驱动程序就不能再涉及缓冲区了。sk_buff是被锁住的(locked),确保其他程序不会存取它。

        数据帧在传送之前先要排成对列,在加入队列之前,还要在每个数据帧的开始添加硬件帧头,这项工作对于数据传送非常必要。网络设备驱动程序提供了一个dev->hard_header()例程,来完成添加硬件帧头的工作。协议层在发送数据之前会在缓冲区的开始留下至少 dev->hard_header_len 长度字节的空闲空间。这样dev->hard_header()程序只要调用 skb_push(),然后正确填入硬件帧头就可以了。

  • 接收数据
        驱动接收来自网络上的数据帧,将其转换为能被网络协议识别的网络缓冲区,然后传递给netif_rx()函数,将数据帧传递到网络协议层做进一步处理。
        网络设备数据结构net_device,是网络驱动最重要的部分,位置在include/linux/netdevice.h。所有的网络设备的信息和操作都保存在设备数据结构中,每注册一个网络设备,都需要提供数据结构中各个域的数据。dev_queue_xmit()和netif_rx()使用了sk_buff结构(意为套接字缓冲区),定义在include/linux/skbuff.h中,用于Linux网络子系统各层间传输数据,是一个双向链表。
        网络设备驱动程序没有关于接收的处理。当它收到数据后都会产生一个中断,中断处理程序调用 dev_alloc_skb(),申请一个大小合适的缓冲区(sk_buff),把从硬件传来的数据放入缓冲区。接着,设备驱动程序分析数据包的类型,把 skb->dev设置为接收数据的设备类型 ,把 skb->protocol 设置为数据帧描述的协议类型,这样,数据帧就可以被发送到正确的协议层。硬件帧头指针保存在 skb->mac.raw中,并且硬件帧头通过调用skb_pull()被去掉,因此网络协议就不涉及硬件的信息。最后还要设置skb->pkt_type,标明链路层数据类型,设备驱动程序必须按以下类型设置skb->pkt_type:

PACKET_BROADCAST     链接层广播地址  

PACKET_MULTICAST      链接层多路地址   

PACKET_SELF                  发给自己的数据帧   

PACKET_OTHERHOST    发向另一个主机的数据帧 (监听模式时会有到) 

        最后,设备驱动程序调用netif_rx()把缓冲区向上传递给协议层。netif_rx()将数据放入处理队列后返回,真正的处理是在中断返回后,可以减少中断时间。一旦netif_rx( )被调用,缓冲区就不在属设备驱动程序所有,它不能被修改,而且设备驱动程序也不能再涉及它了。

        在协议层,接收数据包的流程控制分两个层次: 首先,netif_rx()函数限制了从物理层到协议层的数据帧的数量。第二,每一个套接字都有一个队列,限制从协议层到套接字层的数据帧的数量。在传输方面,驱动程序的dev->tx_queue_len 参数用来限制队列的长度。队列的长度通常是100帧,在进行大量数据传输的高速连接中,它足以容纳下所有等待传输的缓冲区,不会出现大量缓冲区阻塞的情况。在低速连接中,例如Slip 连接,队列的长度长设为10帧左右,因为传输10帧的数据就要花费数秒的时间排列数据。


相关函数
    初始化
int (*init)(struct net_device *dev);
        设备初始化和注册时调用,执行的是底层的确认和检查工作,对硬件资源的配置。
    打开设备
int (*open)(struct net_device *dev);
        网络设备激活的时候调用(设备状态down->up)。主要功能:资源申请、硬件激活等。若驱动作为模块装入,open()里调用MOD_INC_USE_COUNT,将引用计数器加1。
        在用户态执行ifconfig eth0 up命令时,要执行两个任务。首先,它通过ioctl(SIOCSIFADDR)(Socket I/O Control Set Interface Address)赋予地址,然后通过ioctl(SIOCSIFFLAGS)(Socket I/O Control Set Interface Flags)设置dev->flag中的IFF_UP标志以打开接口。这个调用会使得设备的open方法得到调用。类似的,在接口关闭时,ifconfig使用ioctl(SIOCSIFFLAGS)来清理IFF_UP标志,然后调用stop函数。
    关闭设备
int (*stop)(struct net_device *dev);
        关闭时调用(设备状态up->down)。若驱动作为模块装入,stop()中需调用MOD_DEC_USE_COUNT。
    分配缓冲区

struct sk_buff *alloc_skb(unsigned int len, int priority);   

struct sk_buff *dev_alloc_skb(unsigned int len);  

        分配一个缓冲区。alloc_skb函数分配一个缓冲区并初始化skb->data和skb->tail为skb->head。参数len为数据缓冲区的空间大小,通常以L1_CACHE_BYTES字节(对ARM为32)对齐,参数priority为内存分配的优先级。dev_alloc_skb()函数以GFP_ATOMIC优先级进行skb的分配。

    释放缓冲区

void kfree_skb(struct sk_buff *skb);   
void dev_kfree_skb(struct sk_buff *skb);
        sk_buff结构中几个数据指针指向如图:

        对sk_buff操作的几个函数:
unsigned char *skb_put(struct sk_buff *skb, int len);   
unsigned char *skb_push(struct sk_buff *skb, int len);   
unsigned char *skb_pull(struct sk_buff *skb, int len);   
void skb_reserve(struct sk_buff ×skb, int len);  
    操作函数
int (*hard_header)(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);  
        根据先前检索到的源和目的硬件地址建立硬件头
int (*rebuild_header)(struct sk_buff *skb); 
        以太网的mac地址是固定的,为了高效,第一个包去询问mac地址,得到对应的mac地址后就会作为cache把mac地址保存起来。以后每次发包不用询问了,直接把包的地址拷贝出来。
void (*tx_timeout)(struct net_device *dev);  
        数据包发送超时失败时调用。
struct net_device_stats *(*get_stats)(struct net_device *dev);
        统计设备信息。
int (*do_ioctl)(struct net_device *dev, struct ifmap *map);
        事先自定义的ioctl命令。

reference
1、深入分析Linux内核源码
2、Linux驱动程序开发实例
3、Linux驱动修炼之道
Dify实战:智能邮件工作流配置全解析 本文详细解析了如何利用Dify平台配置智能邮件工作流,实现邮件处理的自动化与智能化。内容涵盖从获取邮箱授权、安装插件、安全配置环境变量,到构建邮件发送工作流、创建调用该工作流的智能体(Agent)的完整步骤,并分享了连接知识库实现智能客服、定时发送日报等进阶自动化场景,旨在帮助用户显著提升邮件处理效率。 阅读详情

相关推荐

LightTools 中LCD投影仿真的checkerboard pattern偏振控制技术解析

本文深入解析了在LightTools软件中进行LCD投影仿真时,利用checkerboard pattern(棋盘格图案)结合偏振控制技术来模拟液晶面板像素开关、提升图像对比度的核心方法。文章从实战角度出发,详细拆解了通过设置波片(如1/2波片)和偏振片来操控S光与P光转换的原理,并分享了在LightTools中搭建仿真模型、使用VBA脚本自动化配置参数以提高效率的实用技巧,为光学工程师优化投影系统仿真流程提供了清晰指导。

weixin_29305313的博客 344

邻居子系统之数据发送流程

邻居子系统只影响数据包的发送过程,为了使系统更加灵活,邻居子系统首先引入了一个协议无关层,L3协议只需要和该协议无关层交互即可,如下图所示。 这里面起作用的一个核心数据结构是sturct neigh_ops,每个邻居项都关联一个该结构,L3协议只需要在不同的上下文环境中调用该结构的函数就可以了,具体这些函数指针的实现方是谁,由邻居子系统根据邻居项的状态和各自的逻辑决定。这种设计使得邻居子系统向上...

九天小哥的专栏 810

避开ns-3学习深坑:用sns3模块快速搭建GEO卫星通信仿真(附GitHub代码解读)

本文介绍了如何使用sns3模块快速搭建GEO卫星通信仿真环境,绕过复杂的ns-3底层细节。通过详细的Linux环境配置、sns3模块安装和示例代码解读,帮助开发者快速上手卫星通信仿真,并提供了常见问题的解决方案和性能优化技巧。

weixin_28720573的博客 438

网卡驱动理解

网卡驱动属于数据链路层   1、kernel space(对应于要学的网络子系统)  :     system call interface  给应用程序提供访问网络子系统 protocol agnostic interface 协议无关接口  network protocols     网络协议 device agnostic interface   设备无关接口

lanhxg的专栏 1510

CentOS7下Ollama部署全攻略:从安装到自定义端口配置(附国内加速技巧)

本文详细介绍了在CentOS7系统上部署Ollama的完整流程,包括环境准备、模型下载优化、服务化部署及端口配置等关键步骤。特别针对国内网络环境提供了加速安装方案和镜像源配置技巧,帮助开发者快速搭建稳定的本地AI运行环境。

mmm90的博客 288

Windows 高精度计时器:QueryPerformanceCounter 原理、陷阱与最佳实践

本文深入解析Windows高精度计时器QueryPerformanceCounter(QPC)的工作原理、常见陷阱及最佳实践。QPC通过读取硬件计时器(如TSC)实现微秒级精度,适用于游戏开发、音视频处理等高性能场景。文章详细探讨了多核同步、动态频率调整等挑战,并提供了优化代码示例和性能对比数据。

weixin_33391446的博客 269

Linux内核--网络栈实现分析(十)--网络层之IP协议(下)

本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.youkuaiyun.com/yming0221/article/details/7552455 更多请查看专栏,地址http://blog.youkuaiyun.com/column/details/linux-kernel-net.html 作者:闫明 注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”...

星.云计算 277

无迹卡尔曼滤波 (UKF, Unscented Kalman Filter) 算法详解及案例分析

无迹卡尔曼滤波是一种用于估计非线性系统状态的递归算法。其目标是通过结合系统模型和观测数据,估计系统的最优状态。

闲人编程的博客 2625

用Raw socket自己构造数据包头部

一、原始套接字的创建         只有超级用户才能创建原始套接字。 int sockFd; sockFd = socket(AF_INET, SOCK_RAW, protocol);         其中第3个参数protocol是形如IPPROTO_xxx的某个常值,在头文件中定义,经常不为0。         原始套接字不存在端口号的概念。

王之理想乡 1万+

OpenClaw Windows 安装指南

好的,我来一步一步带你在 Windows 上安装 OpenClaw。

m0_60605453的博客 549

国科大作业考试资料-人工智能原理与算法-2024新编-第十一次作业整理

1、有一位教授想知道学生是否睡眠充足。每天,教授观察学生在课堂 上是否睡觉,并观察他们是否有红眼。教授获得如下的领域知识: (1)没有观察数据时,学生睡眠充足的先验概率为0.7。 (2)给定学生前一天睡眠充足为条件,学生在晚上睡眠充足的概率是0.8;如果前一天睡眠不充足,则是0.3。 (3)如果学生睡眠充足,则红眼的概率是0.2,否则是0.7。 (4)如果学生睡眠充足,则在课堂上睡觉的概率是0.1,否则是0.3。 将这些信息形式化为一个动态贝叶斯网络,使教授可以使用这个网络从观察序列中进行滤波和预

MatsumotoChrikk 1055

【Linux网络模型】

第二章 Linux网络模型。

qq_46005538的博客 1409

基于Simulink的鲸鱼优化算法(WOA)MPPT仿真

摘要:本文介绍了基于Simulink的鲸鱼优化算法(WOA)在光伏MPPT控制中的应用。WOA模拟座头鲸的"气泡网捕食策略",通过包围猎物、螺旋收缩和随机搜索三阶段动态平衡全局探索与局部开发能力,有效解决局部阴影导致的多峰P-V曲线问题。文章详细讲解了WOA-MPPT的Simulink建模过程,包括多峰光伏阵列建模、WOA控制器实现和Boost变换器控制。仿真结果显示,在三种典型工况下,WOA-MPPT的追踪效率>99.3%,动态响应时间<0.15s,性能优于传统算法。最后提出了混合WO

amy_mhd的博客 72

一文了解Docker之网络模型

docker

qq_43649937的博客 7053

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Redis 篇-深入了解在 Linux 的 Redis 网络模型结构及其流程(阻塞 IO、非阻塞 IO、IO 多路复用、异步 IO、信号驱动 IO)

1)抛开持久化不谈,Redis 是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,因此多线程并不会带来巨大的性能提升。2)多线程会导致过多的上下文切换,带来不必要的开销。3)引入多线程会面临线程安全问题,必然要引入线程锁这样的安全手段,实现复杂度增高,而且性能也会大打折扣。

小扳手 4553

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

解析Linux网络模型与Redis的高性能网络架构

基于Linux网络模型,解析Redis的高性能实现

BUPTZhanggg的博客 708

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

redis网络模型解析

redis网络模型

1517

Redis网络模型

Client客户端向Server服务端发送一条命令服务端解析并执行命令,返回响应给客户端因此客户端发送命令的格式、服务端响应结果的格式必须有一个规范,这个规范就是通信协议。

weixin_53622554的博客 1260

【linux网络】Linux内核网络

1、网络基础知识 1.1 网络模型 最常说的网络模型一般有 OSI七层协议模型 TCP/IP四层协议模型 TCP/IP五层协议模型 其模型如下: 网络模型 TCP/IP四层模型 TCP/IP五层模型 OSI七层模型 常见协议 典型设备 功能 应用层 应用层 应用层 HTTP、FTP、 TELNET、 ...

风雨无阻 1738

【C++学习笔记】Linux Reactor网络模型

Reactor网络模型将IO的处理转化为对事件的处理。将IO作为时间进行注册,事件就绪后处理IO。

qq_28416409的博客 761

Linux 网络模型

我们的应用程序也好,还是内核空间也好,都是没有办法直接去物理内存的,而是通过分配一些虚拟内存映射到物理内存中,我们的内核和应用程序去访问虚拟内存的时候,就需要一个虚拟地址,这个地址是一个无符号的整数,比如一个32位的操作系统,他的带宽就是32,他的虚拟地址就是2的32次方,也就是说他寻址的范围就是0~2的32次方, 这片寻址空间对应的就是2的32个字节,就是4GB,这个4GB,会有3个GB分给用户空间,会有1GB给内核系统。:简称FD,是一个从0 开始的无符号整数,用来关联Linux中的一个文件。

weixin_66400215的博客 1032

linux 内核 网络模型,1.3 Linux内核网络开发模型

内核网络子系统复杂异常,其开发方式也变化多端。与其他Linux内核子系统一样,内核网络子系统的开发也是通过Git补丁完成的。你需要通过一个邮件列表(有时是多个)发送这些补丁。它们最终要么被子系统维护者接受,要么被拒绝。基于众多的原因,了解内核网络开发模型很重要。无论你是想更好地理解代码,调试并解决基于Linux内核网络的项目中的问题,还是实现改善和优化性能的补丁,都必须学习大量的知识,如:如何应用...

weixin_42347415的博客 285

Linux select/epoll网络模型

select,epoll网络模型经常在面试中出现,epoll是对poll的优化,是linux下最优秀的网络模型 epoll优点: # 相对select,没有最大并发数限制 /proc/sys/file-max # 数据传递(用户空间跟内核空间)通过共享内存(mmap)方式 # epoll_wait 直接返回被触发的fd对应的一块buffer,不需要遍历所有的fd  

hbjae28666的专栏 636

Redis网络模型、通信协议、内存回收

redis的网络模型,通信协议,内存回收解析

kingandsong的博客 1535

Linux 内核系统架构

描述Linux内核的文章已经有上亿字了但是对于初学者,还是应该多学习多看,毕竟上亿字不能一下子就明白的。即使看了所有的Linux 内核文章,估计也还不是很明白,这时候,还...

嵌入式Linux 4398

Redis原理篇:网络模型剖析

文章摘要:本文详细介绍了Linux网络IO模型及其演进过程,包括阻塞IO、非阻塞IO、IO多路复用(select/poll/epoll)、信号驱动IO和异步IO等五种模型,重点分析了epoll机制的优势和工作原理。随后探讨了Redis的网络模型,指出其核心处理采用单线程设计的原因在于避免多线程带来的性能损耗和安全问题,同时揭示了Redis在不同版本中引入多线程的演进过程。文章通过对比各种IO模型的性能特点,阐明了epoll作为高效IO多路复用机制的技术优势,以及Redis选择单线程架构的设计考量。(149字

2301_79949064的博客 977
上一篇: Linux内核代码笔记5----I/O体系结构和设备驱动模型
下一篇: Linux下编译Vim自动补全神器YouCompleteMe(ycm)
up2wing
博客等级 码龄17年 11粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值