内核协议栈1

开始看协议栈了,采用从底向下的结构来介绍网络协议栈中涉及到的数据结构。
我一般采用在线的读源码。
地址:http://lxr.linux.no

在这里没有原创,只是学习心得。

1. net_device 结构 , 是网络设备的一个抽象,里面的属性很多,不需要全看明白,也蛮难看懂的。尝试着看,
看不明白的时候就记着属性名字,到后面看到用这个属性的时候一定要回想起来,这样就行了。net_device结构的设计
有点问题,它将函数接口和数据属性设计到了一起,导致这个结构十分的庞杂。

一个结构出来了,之后就是关于这个结构如何组织,如何分配,如何释放,以及对这个结构可以进行的操作了,
net_device在内核中的组织采用了链表来组织,用一个dev_base指针来索引这个链表,同时net_device这个
设备还被组织到了dev_name_head和dev_index_head两个散列表之中,方便根据名字和下标来进行所以设备,
这些就是net_device的组织存储结构了。

分配释放操作之中,这牵扯的函数就有一大堆了,然后看函数也不用死啃,这是啃不明白的,除非你有一个很好的阅
读源码的工具,能够很方便知道哪个宏在哪,对C语言掌握很好,指针什么的也理解的不错。 要不然就慢慢来,不要
期望一次性就能读通。网络设备的初始化,打开,关闭,发送数据,接收数据这些函数都得看,关键是记住与其他模块
的接口部分,一定要记清楚。

总体关于网络设备:
网络设备在内核中被抽象为struct net device结构, 网络设备链表, 网络设备的创建,注册和注销,
网络设备的开启和关闭,网络设备的通知链。这些就是网络设备的内容,现在知道内核中有这么一个结构来代表网络
设备就行了。慢慢的后面就会建立联系的。

2. in_device结构,net_device代表一个网络设备,那么网络设备应存在IP相关的信息。保存这些信息的结构就
是in_device结构,它是net_device结构中的一个成员,它保存了所有关于IPV4的配置,可以深入到它的结构内部
来看,它又有一个成员ifa_list,这个成员指向的是一个strct in_ifaddr结构组成的链表,链表的每一个节点保
存的是IP地址,子网掩码,广播地址等信息。会不会有疑问,为什么需要一个链表来记录,每个主机不就一个IP地址么,
我的理解是,IP地址是对应的网络接口的,不是对应于主机的,比如路由器有多个网络接口,因此它有多个IP地址信息,
因此需要用链表来保存,书上没明说,但是我猜想应该是这个原因。

结构出来了,对应的操作应该是马上就要出来了。in_device保存的是IPV4配置块(包含一些杂七杂八的信息),
由这个配置块可以找到很多的IP地址,这个配置块又可以由net_device结构来得到。与in_device相关的函数有初
始化,注销,IP地址设置等等。有些函数可以去看看。 这里还要介绍一些常用的设置IP地址的接口,通常我们都用
ifconfig来设置IP地址,它的实质是通过ioctl接口来对网络设备进行操作和配置的,会不会感觉好复杂,下面我来说
说我的理解,看整个网络内核的时候,我就分了两层,应用层,内核层,网络书籍上告诉你的那些层其实都是一些内核的函数集合
构成的。 可以这么来说,网络书上的每一个层的概念就是一些功能函数的集合,有人或许会说是废话,但是刚看那个七层体系
或者四层体系的人,脑海中是不会有这个概念的。 换句话说,这些函数都是在内核里面,linux将其这么设计的目的就是
每个层比较好移植,设计成体系的原因就是便于移植和更改。这跟我现在说的ioctl接口有关系么? 答案是有的,
前面说到我就分两层来看,ioctl接口无非是进入到内核层设置,内核里面最高权限了,设置一个内核的数据in_device还不是
手到擒来? 所以不要觉得ioctl是很神奇的东西,它不就是你C语言编程的一个函数么,在它的作用域里面的变量不是想改就改?想用就用?
至于接口怎么实现的,就自己看书吧,有了上面我介绍的思维,看个大概应该不难。

-----我看的书籍之中关于网络设备这一块重要的数据结构就是这些。
下面有必要对linux内核中链表和散列表的实现原理进行分析。

linux链表真是设计的好,这才理解了编程的精髓。

http://blog.csdn.net/shendl/article/details/6605207
csdn上的介绍。

https://www.ibm.com/developerworks/cn/linux/kernel/l-chain/
IBM上的介绍。

http://apps.hi.baidu.com/share/detail/9052699
关于C语言define的用法详解。方便读内核。


关于链表的用法很简单,就是采用了数据包含链表的方式,非常的方便,然后对于重要的遍历操作中,重要的一点是如何由链表节点得到数据节点的
这里面用到了几个很关键的宏,需要慢慢的推敲,虽然表面上使用了0地址,但是实际上只是得到并没有对地址进行写操作,编译方面的处理。

在include/linux/list.h里面有关于链表和散列链表的实现,需要好好的读一下。了解内核中最基本的数据结构。


同时需要了解linux内核内部关于数据转换的部分,这部分的内容十分重要

原文地址:https://www.cnblogs.com/hpf311/p/2576081.html