LC-trie 快速路由查找算法
一般来说我们把字典树称作 trie,这是一个用于查找字符串的数据结构,举个简单的例子。下面就是一个把 b,abc,abd,bcd,abcd,efg,hii 这 6 个单词构造成字典树的例子。
一般来说我们把字典树称作 trie,这是一个用于查找字符串的数据结构,举个简单的例子。下面就是一个把 b,abc,abd,bcd,abcd,efg,hii 这 6 个单词构造成字典树的例子。
neighbor 在协议栈里指的是同一个 LAN 下面的邻居,也就是他们在 L3 上通过媒介或者点对点连接在了一起。邻居子系统同时也可以理解为一个 L2 和 L3 地址的转换器。邻居子系统的目的就在于上层协议不应该关心下层的地址信息,我发送过来的 IP 地址应该让下层来决定发送到哪个 MAC 地址。neighbor solicitation and neighbor advertisement,可以分别对应 ARP 的 request 请求和 ARP 的 reply 请求。
邻居子系统主要缓存两大块的内容,一个是 L3 到 L2 的映射解析的缓存,一个是 L2 头的缓存,缓存 L2 头的原因是大部分 L2 的头基本上是重复的,所以通过缓存头部可以加快协议的封装。
以下有几个相关结构体需要介绍一下。
struct neighbour 代表的是一个邻居的信息,比如 L2 和 L3 地址等。
struct neigh_table 代表的是一种邻居协议的接口(比如 ARP)。
struct neigh_params 代表的是邻居协议在每个设备上的不同参数。
struct neigh_ops 邻居对应的一些操作函数。
struct hh_cache 缓存 L2 的头部,不是所有的设备都支持头部缓存。
struct rttable 和 struct dst_enry, IPv4 的路由缓存信息是通过 struct rttable 缓存的。
这是 dst_entry, hh_cache 和 neighbour 之间的关系。
neighbor 结构是用 hash 存储的,key 是 L3 地址加设备(对应的 device 结构体)加一个随机值。hash 表通过 neigh_hash_alloc 和 neigh_hash_free 来分配和释放。neigh_lookup 就是通过 key 从 hash table 中找到对应的 neighbour 结构体,实现都不复杂,这里理解就可以了。
一般邻居子系统的缓存流程是这样的,如果 L3 的请求到达,地址解析缓存没有命中,把 L3 packet 入队,开始neighbor solicitation 等收到 neighbor advertisement 之后再出队并且发送。
ip 分片的主体函数在 ip_fragment 当中,重组则在 ip_defrag 当中。第一个分片的标志 Offset 为 0,MF 为 1,之后的分片则是 Offset 非 0,MF 为 1,最后一个分片则是 Offset 非 0,但是 MF 为 0。以此来分别当前的 IP packet 是否是一个分片。从 IP 层向上层协议发送数据包的时候就会进行重组,比如在 ip_local_deliver 当中,调用了。说一句题外话, TCP 有 MSS ,保障 TCP message 不超过分片大小,这样是一种对底层协议有感知的行为。
1 | if (ip_is_fragment(ip_hdr(skb))) { |