题主应该是没做过路由器或者交换机,所以把路由器想象成一个类似于APP之类的东西。
实际上,路由器相当于一台计算机,而OSPF相当于计算机里的一个程序。同时,BGP,RIP,报文转发,IP路由表维护等等,这些都类似于一个一个独立的程序。
在OSPF内部,是存储了当前OSPF路由协议范围内的拓扑信息的,这个拓扑信息,只要OSPF建立起邻居关系就有了,并且一直存在。
在IP路由表这个模块程序里,它是不负责存储任何拓扑结构的,IP表里只有一个的东西,就是某个目的地址的下一跳是哪里——也就是路由表。
在路由器里,各种路由协议都是独立运行的,甚至某个路由协议还有多个实例(OSPF多实例),每个路由协议根据自己协议的情况获取网络拓扑情况,并计算出协议内的最优路由表,然后把这个路由表通告给IP路由模块。
IP路由模块可能会同时收到不同协议下、不同结果的路由信息,IP路由模块唯一的工作就是根据优先级选路,以及计算递归路由。
IP路由模块计算完最终生效的路由表以后,会下发给二层模块,二层模块会根据下一跳信息计算出具体报文要经过哪个二层接口(可能是虚拟的,也可能是物理的)发出,同时还要考虑到负载平衡等因素。
二层处理完这些信息以后,会通知物理层驱动去操作硬件,完成路由表写入硬件的动作。
所以:
1. IP路由表里不储存完整路由和拓扑信息,它只负责选路;
2. 各个协议内部自己维护自己的路由表,这个路由表跟IP层看到的,不一定相同,这些信息一般情况下都保存在内存中,可能是链表,可能是数组,也可能是其它形式;
3. 不存在“执行协议”这个动作,不同层次的驱动做不同的事情。
不知道题主是不是要实现OSPF协议,事先说明,OSPF协议非常复杂,即使实现基本功能,也需要大量的代码(几万行),这还不包括协议的支撑部分(核心路由管理)。
OSPF路由表的数据结构是一个route_entry的结构:
1. 需要一个指针指向一个二叉树(或者就是一个树),二叉树里是具体的路由结构。为什么是个二叉树呢,因为路由是可能合并的。
2. 需要一个path的vector,也就是路径节点。
3. 需要一些辅助信息,比如metric,distance等。
4. 需要一个selected_path指向一个path_entry的结构,也就是选路的具体信息。
path_entry里需要包含的成员有:
1. 各种辅助信息,比如类型、flag、metric之类
2. area号
3. 一个vector成员记录着下一跳信息
4. 一个vector成员记录着对应的lsa信息
5. 一个path_entry指向最终的、翻译后的path
以上是路由表的结构,需要route_entry和path_entry两套。
同时,LSA这些还需要额外的数据结构。
一套商业的OSPF代码大概需要5-10万行代码才能实现。不包含底层驱动,不包含核心表。
评论区有人推荐用zebra,我查了一下,这个东西就是我评论里提到的ZebOS的开源版本,在这里:
Zebra - Free Software Directory
可以下载到一个副本(页面右侧链接),貌似现在这个版本维护的比较少了。我做路由协议这一块是十几年前的事情了,对最新的技术状态不是特别了解。