2010-03-30 ipip.c in linux
今天看了看内核里面实现的ipip,终于把它给看下去了。
内核里面实现的时候,首先定义一个tunnel类型的结构体,在这个结构体有一个指针指向一个net_device{},然后这个net_device{}里面的priv指针又指向这个tunnel类型的结构体,所以一个tunnel和一个net_device一一对应。里面定义了一个ipip_net,这是一个储存tunnel的hash表。里面有对三种类型的hash函数计算方法。通过这种方式可以在机器上面配置和管理很多个隧道。
在每一个tunnel上面,有一个ip_tunnel_parm{},里面有一个iphdr{},通过这个ip头部上面的源地址和目的地址来区分不同的tunnel。在配置的时候,应该使用ip tunnel命令传入一个remote的值和local的值,然后,这个值就被用于查找tunnel,如果这个(remote,local)没有的话,就会创建一个tunnel,一个tunnel用一个(remote,local)对来代替。在bind()函数里面,就已经通过路由来查找通向remote的路径。
在发送的时候,包裹在一个ip头部里面,ip的头部的源地址和目的地址是分别从路由的结果中得到的,路由的源地址和目的地址分别是该路径的源地址和目的地址。(不明白为什么不直接是tunnel的源地址和目的地址,有可能是为了照顾当tunnel的两端分别是两个子网的时候,这个时候任意一台的机器可以和对方的任意一台机器连接。)
当然,除此之外,linux没有给予任何信息,比如说没有说明邻居。一个ip包应该发送到哪儿呢?所以现在这种情况下的linux的信息是不够的,还需要通过配置设备,配置地址和路由来达到这个目的。