Linux 路由 学习笔记 之一 相关的数据结构
http://blog.csdn.net/lickylin/article/details/38326719
从现在开始学习路由相关的代码,在分析代码之前, 我们还是先分析数据结构,把数据结构之间的关系理解了以后,再理解代码就相对轻松多了。本小节先分析路由相关的数据结构。内核里面大多模块定义的数据结构之间一般都是使用链表或者hash表实现连接操作。
对于路由表,相关的数据结构有fib_table、fn_hash、fn_zone、fib_node、fib_alias、fib_info、fib_nh等, 下面分别介绍这几个数据结构
路由表结构,该结构为一个路由表的抽象,包括路由表的id、路由添加函数、路由查找函数、路由删除函数等
- struct fib_table {
 - /*使用hash链表将多个路由表变量链接在一起*/
 - struct hlist_node tb_hlist;
 - /*表id*/
 - u32 tb_id;
 - unsigned tb_stamp;
 - /*路由查找函数*/
 - int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
 - /*路由插入函数*/
 - int (*tb_insert)(struct fib_table *, struct fib_config *);
 - /*路由项删除函数*/
 - int (*tb_delete)(struct fib_table *, struct fib_config *);
 - int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
 - struct netlink_callback *cb);
 - /*清空路由表的规则*/
 - int (*tb_flush)(struct fib_table *table);
 - void (*tb_select_default)(struct fib_table *table,
 - const struct flowi *flp, struct fib_result *res);
 - /*可变长数组,主要是用来指向掩码相关的hash数组*/
 - unsigned char tb_data[0];
 - };
 
该结构主要用于描述以掩码划分的区域结构以及掩码区域之间的关系
对于ipv4来说,掩码可以为0-32共33种可能,因此对于一个fn_hash来说,则
定义了一个包含33个fn_zone的数组,而链表fn_zone_list,主要是将一个路由表里的
fn_zone链接在一起(以掩码大小的顺序排列,主要是在路由查找时,先匹配最长掩码对应的路由,以提高路由匹配的精确度)。
- struct fn_hash {
 - struct fn_zone *fn_zones[33];
 - struct fn_zone *fn_zone_list;
 - };
 
以掩码划分的区域结构抽象,将掩码长度相同的所有路由放在同一个fn_zone中hash表中。
- struct fn_zone {
 - /*指向下一个非空的fn_zone*/
 - struct fn_zone *fz_next;
 - /*指向路由项关联的hash链表,对于掩码相关的目的ip地址,根据目的网络地址
 - 的hash值,将新的fn_node节点插入到相应的hash链表中*/
 - struct hlist_head *fz_hash; /* Hash table pointer */
 - /*fn_node结构变量的个数,fn_node并不能说是对一个路由项的抽象,可以看成对一个
 - 目的网络地址的抽象,而对于相同的目的网络地址,可以根据tos、priority、mark值创建
 - 不同的路由,所以一个fn_node结构中fn_alias才能算作是对一个路由项的抽象*/
 - int fz_nent; /* Number of entries */
 - /*该fn_zone中fz_hash链表的个数*/
 - int fz_divisor; /* Hash divisor */
 - /*fz_hash的mask值*/
 - u32 fz_hashmask; /* (fz_divisor - 1) */
 - #define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
 - /*以上两个值用于fz_hash数组的容量扩充相关*/
 - /*该fn_zone对应的掩码长度*/
 - int fz_order; /* Zone order */
 - /*根据fz_order而得到的掩码值*/
 - __be32 fz_mask;
 - /*获取该fn_zone对应的掩码值*/
 - #define FZ_MASK(fz) ((fz)->fz_mask)
 - };
 
抽象为一个目的网络地址相同的所有路由项的基础结构,其中的fn_alias,表示该结构所包含的已存在的路由项的链表,fn_key为该结构对应的目的网络地址值,
用于和掩码长度相同的其他fib_node区分,对于同一个fn_zone里的fib_node,都链接到fn_zone->fz_hash中相应的hash表中
- struct fib_node {
 - /*用于将hash值相同,且目的网络地址值不同,且网络掩
 - 码相同的fib_node变量链接在一起*/
 - struct hlist_node fn_hash;
 - struct list_head fn_alias;
 - __be32 fn_key;
 - };
 
该结构可以理解为一个路由项的抽象。
当路由项的目的网络地址相同时,可以根据这个结构变量区分不同的路由项。包括tos、type、scope、state以及fib_info来区分一个路由项
方法:
1.首先根据tos、type、scope等确定一个fib_alias
2.当fib_alias确定以后,再根据priority等值确定一个fib_info,
3.根据fib_info确定出口设备与下一跳网关的ip地址。
- struct fib_alias {
 - struct list_head fa_list;
 - struct rcu_head rcu;
 - struct fib_info *fa_info;
 - u8 fa_tos;
 - u8 fa_type;
 - u8 fa_scope;
 - u8 fa_state;
 - };
 
而fa_scope表示路由的scope,取值范围如下:
RT_SCOPE_UNIVERSE:该选项用于所有通向非直连目的地的路由表项,即
应用层创建的路由中包含via的路由
RT_SCOPE_LINK:该选项用于目的地址为本地网络的路由项
RT_SCOPE_HOST:该选项用于路由为本机接口,
RT_SCOPE_NOWHERE:该选项用于路由不可到达
- enum rt_scope_t
 - {
 - RT_SCOPE_UNIVERSE=0,
 - /* User defined values */
 - RT_SCOPE_SITE=200,
 - RT_SCOPE_LINK=253,
 - RT_SCOPE_HOST=254,
 - RT_SCOPE_NOWHERE=255
 - };
 
功能:主要是用来获取出口设备以及下一跳网关的数据结构,以及路由项的优先级,路由创建协议fib_protocol(RTPROTO_KERNEL、RTPROTO_BOOT、RTPROTO_STATIC等取值)。而fib_hash与fib_lhash则是将fib_info链接到对应的hash链表fib_info_hash[]与fib_info_laddrhash[]中去的。
- struct fib_info {
 - /*这两个指针用于将该fib_info链接到hash链表中*/
 - struct hlist_node fib_hash;
 - struct hlist_node fib_lhash;
 - int fib_treeref;
 - atomic_t fib_clntref;
 - /*标识是否将要释放该fib_info变量*/
 - int fib_dead;
 - unsigned fib_flags;
 - int fib_protocol;
 - __be32 fib_prefsrc;
 - /*优先级*/
 - u32 fib_priority;
 - u32 fib_metrics[RTAX_MAX];
 - #define fib_mtu fib_metrics[RTAX_MTU-1]
 - #define fib_window fib_metrics[RTAX_WINDOW-1]
 - #define fib_rtt fib_metrics[RTAX_RTT-1]
 - #define fib_advmss fib_metrics[RTAX_ADVMSS-1]
 - /*fib_nh变量的个数*/
 - int fib_nhs;
 - #ifdef CONFIG_IP_ROUTE_MULTIPATH
 - int fib_power;
 - #endif
 - #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
 - u32 fib_mp_alg;
 - #endif
 - /*可变长度数组,用于动态申请fib_nh内存空间*/
 - struct fib_nh fib_nh[0];
 - #define fib_dev fib_nh[0].nh_dev
 - };
 
包含下一跳网关及出口设备的结构
- struct fib_nh {
 - /*数据包输出设备接口*/
 - struct net_device *nh_dev;
 - /*将fib_nh变量链接在hash链表中*/
 - struct hlist_node nh_hash;
 - /*包含该变量的fib_info变量*/
 - struct fib_info *nh_parent;
 - unsigned nh_flags;
 - unsigned char nh_scope;
 - #ifdef CONFIG_IP_ROUTE_MULTIPATH
 - int nh_weight;
 - int nh_power;
 - #endif
 - #ifdef CONFIG_NET_CLS_ROUTE
 - __u32 nh_tclassid;
 - #endif
 - /*出口设备的index*/
 - int nh_oif;
 - /*下一跳网关地址*/
 - __be32 nh_gw;
 - };
 
而nh_hash是用来将fib_nh变量链接到对应的fib_info_devhash[]链表中的。
以上就是相应的数据结构分析,下面是这些数据结构之间的逻辑关系。没有给出fib_info_hash[]、fib_info_laddrhash[]与fib_info之间的,也没有给出fib_nh与fib_info_devhash之间的关系
以上就是路由相关的数据结构,下一节开始分析路由的添加与删除等功能。以上分析的数据结构没有包含路由缓存相关的数据结构,等到介绍到路由缓存时再进行分析。
Linux 路由 学习笔记 之一 相关的数据结构的更多相关文章
- Linux系统学习笔记:文件I/O
		
Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...
 - linux kernel学习笔记-5内存管理_转
		
void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...
 - Linux内核学习笔记二——进程
		
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
 - Linux命令学习笔记目录
		
Linux命令学习笔记目录 最近正在使用,linux,顺便将用到的命令整理了一下. 一. 文件目录操作命令: 0.linux命令学习笔记(0):man 命令 1.linux命令学习笔记(1):ls命令 ...
 - 尚硅谷韩顺平Linux教程学习笔记
		
目录 尚硅谷韩顺平Linux教程学习笔记 写在前面 虚拟机 Linux目录结构 远程登录Linux系统 vi和vim编辑器 关机.重启和用户登录注销 用户管理 实用指令 组管理和权限管理 定时任务调度 ...
 - linux 驱动学习笔记01--Linux 内核的编译
		
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
 - Linux内核学习笔记-2.进程管理
		
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
 - Linux内核学习笔记-1.简介和入门
		
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
 - MySQL学习笔记-事务相关话题
		
事务机制 事务(Transaction)是数据库区别于文件系统的重要特性之一.事务会把数据库从一种一致状态转换为另一个种一致状态.在数据库提交工作时,可以确保其要么所有修改都已经保存了,要么所有修改都 ...
 
随机推荐
- 【转载】jquery实现勾选复选框触发事件给input赋值+回显复选框
			
引用:https://blog.csdn.net/rui276933335/article/details/45717461 JSP: <td class="as1"> ...
 - STM32F407+STemwin学习笔记之STemwin移植补充Touch
			
原文地址:http://www.cnblogs.com/NickQ/p/8857213.html 环境:keil5.20 STM32F407ZGT6 LCD(320*240) STemwin:S ...
 - 棋盘覆盖(我们学校自己的UOJ上的变形题)
			
题目 #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> # ...
 - Python概述
			
1.什么是Python? Python是一种解释型,面向对象,动态数据类型的高级程序设计语言. Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年. 像 ...
 - 武汉Uber优步司机奖励政策(12月28日到1月3日)
			
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
 - 长沙Uber司机奖励政策(8月24日到8月30日)
			
本周奖励(8月24日到8月30日) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://w ...
 - 在线tidb+tipd+tikv扩容,迁移,从UC到阿里云
			
集群现状: 共有五个节点,配置为16核32g内存,数据节点为1T ssd盘,非数据节点为100g ssd盘: 角色规划: node1 tidb tipd node2 tidb tipd node3 t ...
 - Mybatis JPA 插件简介
			
前段时间了解到Spring JPA,感觉挺好用,但其依赖于Hibernate,本人看到Hibernate就头大(不是说Hibernate不好哈,而是进阶太难),于是做了一个迷你版的Mybatis JP ...
 - cf#516A. Make a triangle!(三角形)
			
http://codeforces.com/contest/1064/problem/A 题意:给出三角形的三条边,问要让他组成三角形需要增加多少长度 题解:规律:如果给出的三条边不能组成三角形,那答 ...
 - hdu1422重温世界杯(动态规划,最长子序列)
			
重温世界杯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...