您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第16章 Linux内核中网络部分结构以及分布
第16章Linux内核中网络部分结构以及分布第5章到第15章介绍了Linux环境下的用户层网络编程知识,基本上可以满足进行应用程序开发的需要。从本章开始,第16章和第17章介绍Linux内核层网络架构,主要介绍如何基于Netfileter框架在Linux的内核层挂接自己的网络数据处理函数,对内核层网络数据进行过滤。本章介绍内核层网络架构的基本知识,分为如下几个部分:内核中网络相关代码的基本情况:内核层的网络代码分布情况,内核层的网络处理流程,内核层提供的用户处理网络数据的可插入点,内核层的数据结构及编程框架等处理内核层网络数据的基本技术。简单介绍netfilter介绍Iptables,如何使用Iptables控制netfilter。介绍内核层的软中断报文队列处理方式。介绍中断处理下半部的要点和方式。介绍与一个socket有关的数据如何在内核层处理。16.1概述Linux网络协议栈的实现在内核代码中,了解Linux内核的网络部分代码有助于深刻理解网络编程的概念。Linux内核层还提供了网络防火墙的框架netfilter,基于netfilter框架编写网络过滤程序是Linux环境下内核层网络处理的常用方法。16.1.1代码目录分布Linux的内核源代码可以去网站下载,本书使用Linux-2.6.26.3版本(可能不是最新版本,读者可以去下载最新的版本)。/usrsrclinux-2.6.26.3Documentationcrytofsdriversinitincludekernelipcmmlibblockarchnetscriptssamplessecurityusrsoundvirt16.1.2内核中网络部分流程简介网络协议栈是由若干个层组成的,网络数据的流程主要是指在协议栈的各个层之间的传递。在第七章第一节里介绍了TCP网络编程的流程,一个TCP服务器的流程按照建立socket(),绑定(bind())地址端口,侦听端口listen(),接收连接accept(),发送数据send(),接收数据recv(),关闭socket()的顺序来进行的。与此对应内核的处理过程也是按照此种顺序进行的,网络数据在内核中的处理过程主要是在网卡和协议栈之间进行:从网卡接收数据,交给协议栈处理;协议栈将需要发送的数据通过网络发出去。16.1.2内核中网络部分流程简介插口层(socket)进程协议层(TCP、UDP、IP、ICMP、IGMP等)接口层函数调用启动输出接口队列协议队列(IP输入队列)插口队列软中断(由接口层产生)硬中断(由网络设备产生)应用层系统调用接口协议诊断接口网络协议设备诊断接口设备驱动硬件设备用户空间内核空间16.1.3系统提供修改网络流程点上节介绍了网络数据在内核中的流程,网络中的数据在通常情况下按照上节所述的流程传递。Linux内核中还提供了一种灵活修改网络数据的机制,用户可以利用这种机制获得和修改内核层的网络数据和属性设置。数据流向检查点用户处理16.1.4结构sk_buff内核层和用户层在网络方面的差别很大,在内核的网络层中sk_buff结构占有重要的地位,几乎所有的处理均与此结构有关系。网络协议栈是一个层次架构的软件结构,层与层之间通过预订的接口传递报文。网络报文中包含了在协议各层使用到的各种信息。由于网络报文之间的大小不是固定的,因此采用合适的数据结构来存储这些网络网络报文就1.结构sk_buff的原型2.sk_buff的含义16.1.4结构sk_buffheaddatatailend数据frag_listfrag_list[0]frag_list[1]frag_list[2]...frags[MAX_SKB_FRAGS]内存片内存片页碎片区sk_buff结构网络报文存储区从属skbuff1从属skbuff链表区从属skbuff216.1.5网络协议数据结构inet_protosw第5章中对TCP/IP的网络协议族进行了介绍(IP、TCP、UDP等)。其中协议TCP、UDP、RAW三种在文件Linux-2.6.26.3/net/ipv4/af_inet.c中一个名为inet_init()的函数中进行了初始化(因为TCP和UDP都是inet簇协议的一部分)。inet_init()函数使用proto_register()函数来注册每个内嵌协议。通过Linux/net/ipv4/目录中tcp.c和raw.c文件中的proto接口,可以了解各个协议是如何标识自己的。这些协议接口每个都按照类型和协议映射到inetsw_array,该数组将内嵌协议与操作映射到一起。inetsw_array结构及其关系如图16-8所示。最初,会调用inet_init()中的inet_register_protosw()将这个数组中的每个协议都初始化为inetsw。函数inet_init()也会对各个inet模块进行初始化,例如ARP、ICMP和IP模块,以及TCP和UDP模块。16.1.5网络协议数据结构inet_protoswSOCK_STREAMIPPROTO_TCP&tcp_prot&inet_stream_ops...SOCK_DGRAMIPPROTO_UDP&udp_prot&inet_dgram_ops...SOCK_RAWIPPROTO_IP&raw_prot&inet_sockraw_ops…UDPTHIS_MODULEudp_lib_closeip4_datagram_connect...PF_INETTHIS_MODULEinet_releaseinet_bind...structproto_opsinet_dgram_opsstructprotoudp_protstructinet_protoswinetsw_array[]16.2软中断CPU报文队列及其处理软中断是Linux内核中的一种概念,它利用硬件中的中断概念,用软件方式对此进行模拟,实现相似的执行效果。16.2.1Linux内核网络协议层的层间传递手段—软中断网络协议栈是分层实现的,如何实现高效的网络数据是协议栈设计的核心问题之一。1.Linux内核中软中断的机制2.Linux内核中软中断的使用方法软中断守护内核线程软中断向量表软中断状态void(*action)(structsoftirq_action*)void*data软中断向量结构16.2.2网络收发处理软中断的实现机制网络收发的处理通过软中断进行处理为一个软中断,考虑到优先级问题,分别占用了向量表中的2号和3号软中断来分别处理接收和发送。软中断守护内核线程软中断向量表软中断状态void(*action)(structsoftirq_action*)void*data软中断向量结构中断处理函数网络软中断处理程序网络软中断回调16.3socket数据如何在内核中接收和发送socket数据在内核中的流程主要包含初始化、销毁、接收和发送网络数据。其过程涉及到网卡驱动、网络协议栈和应用层的接口函数。16.3.1socket()的初始化在初始化套接字的时候,同时初始化socket的操作函数(proto_ops结构)。如果传入的type参数是STREAM类型,那么就初始化为SOCKET-ops为inet_stream_ops。参数inet_stream_ops是一个结构体,包含了stream类型的socket操作的一些入口函数。在这些函数里主要做的是对socket进行相关的操作。创建socket的同时还创建一个sock结构的数据空间。初始化sock,初始化过程主要做的事情是初始化三个队列:receive_queue(接收到的数据包sk_buff链表队列),send_queue(需要发送数据包的sk_buff链表队列),backlog_queue(主要用于tcp中三次握手成功的那些数据包)。根据family、type参数,初始化sock的操作,例如对于family为inet类型的,type为stream类型的,sock-proto初始化为tcp_prot,其中包括stream类型的协议sock操作对应的入口函数。应用层关闭socket时,内核需要释放所关闭socket申请的资源。16.3.2接收网络数据recv()网络数据接收依次经过网卡驱动和协议栈程序,以DM9000A网卡为例进行介绍接收数据的过程。如图16-11所示,网卡在一个数据包到来时,会产生一个硬中断,网络驱动程序会执行中断处理过程:首先申请一个skb结构及pkt_len+5大小的内存用于保存数据,然后便将接收到的数据从网卡复制到这个skb的数据部分中。当数据从网卡中成功接收后,调用netif_rx(skb)进一步处理数据,将skb加入到相应的input_pkt_queue队列中,并调用netif_rx_schedule(),会产生一个软中断来执行网络协议栈的例程。这样,中断的上半部已完成,以下的工作则交由中断的下半部来实现。16.3.3发送网络数据send()Linux对网络数据的发送过程的处理与接收过程相反。在一端对socket进行write()的过程中,首先会把要write的字符串缓冲区整理成msghdr的数据结构形式,然后调用sock_sendmsg()把msghdr的数据传送至inet层。send构建skb添加TCP/UDP数据添加IP数据ip_senddev_queue_xmit网络驱动发送数据16.4小结本章介绍了Linux内核代码的架构,特别是网络相关的部分,并对结构sk_buff进行了详细的分析,简单分析了网络数据的流程。介绍了Linux的软中断方式,对网络协议栈中使用的软中断处理报文队列的方式进行了简单介绍。对插口层的网络数据发送接收的流程进行了分析。
本文标题:第16章 Linux内核中网络部分结构以及分布
链接地址:https://www.777doc.com/doc-3729143 .html