linux路由 guagga,(2) quagga源码分析--路由信息处理zebra-rib

对于各个协议生成的路由信息的处理属于quagga中非常重要的一个功能,如何在内核进行路由增加,更新,删除是一个复杂的过程。

quagga在thread任务调度中加入了一种工作队列,work_queue,与内核的工作队列类似,是一种相对而言,低优先级的任务,这里的任务看成类似的系统进程。

1、队列初始化:

93e3ef9b3ca94f69293e948223078d88.gif

1 /*initialise zebra rib work queue*/

2 static void

3 rib_queue_init(struct zebra_t *zebra)4 {5 assert(zebra);6

7 if (!(zebra->ribq = work_queue_new(zebra->master,8 "route_node processing")))9 {10 zlog_err("%s: could not initialise work queue!", __func__);11 return;12 }13

14 /*fill in the work queue spec*/

15 zebra->ribq->spec.workfunc = &meta_queue_process;16 zebra->ribq->spec.errorfunc =NULL;17 /*XXX: TODO: These should be runtime configurable via vty*/

18 zebra->ribq->spec.max_retries = 3;19 zebra->ribq->spec.hold =rib_process_hold_time;20

21 if (!(zebra->mq =meta_queue_new()))22 {23 zlog_err("%s: could not initialise meta queue!", __func__);24 return;25 }26 return;27 }

93e3ef9b3ca94f69293e948223078d88.gif

第19行,zebra->ribq->spec.hold =rib_process_hold_time; 指定了rib工作队列在thread_fetch的时候会等待10毫秒

1 /*Hold time for RIB process, should be very minimal.2 * it is useful to able to set it otherwise for testing, hence exported3 * as global here for test-rig code.4 */

5 int rib_process_hold_time = 10;

在添加thread任务的时候进行了时间单位换算:

93e3ef9b3ca94f69293e948223078d88.gif

1 /*Add a background thread, with an optional millisec delay*/

2 struct thread*

3 funcname_thread_add_background(struct thread_master *m,4 int (*func)(struct thread *),5 void *arg, longdelay,6 debugargdef) {7 structtimeval trel;8

9 assert(m !=NULL);10

11 if(delay) {12 trel.tv_sec = delay / 1000;13 trel.tv_usec = 1000 * (delay % 1000);14 } else{15 trel.tv_sec = 0;16 trel.tv_usec = 0;17 }18

19 returnfuncname_thread_add_timer_timeval(m, func, THREAD_BACKGROUND,20 arg, &trel, debugargpass);21 }

93e3ef9b3ca94f69293e948223078d88.gif

OK,meta_queue_process,就指定了工作队列在调度执行的处理函数,由此guagga就会一直同步更新路由了。

2、每个子网的下一跳路由表项的描述:

quagga使用了双向链表来管理表项,定义了路由表现的详细信息,但比如 status 这个字段是用来在更新路由时来做比较的关键字段。如下宏定义了3种状态:

#define RIB_ENTRY_REMOVED    (1 << 0)

#define RIB_ENTRY_CHANGED    (1 << 1)

#define RIB_ENTRY_SELECTED_FIB    (1 << 2)

93e3ef9b3ca94f69293e948223078d88.gif

1 structrib {2 struct rib *next; /*Link list.*/

3 struct rib *prev;4 struct nexthop *nexthop; /*Nexthop structure*/

5 unsigned long refcnt; /*Refrence count.*/

6 time_t uptime; /*Uptime.*/

7 int type; /*Type fo this route.*/

8 vrf_id_t vrf_id; /*VRF identifier.*/

9 int table; /*Which routing table*/

10 u_int32_t metric; /*Metric*/

11 u_int32_t mtu; /*MTU*/

12 u_int32_t nexthop_mtu;13 u_char distance; /*Distance.*/

14 u_char flags; /*Flags of this route. in lib/zebra.h ZEBRA_FLAG_**/

15 u_char status; /*RIB internal status*/

16 #define RIB_ENTRY_REMOVED (1 << 0)

17 #define RIB_ENTRY_CHANGED (1 << 1)

18 #define RIB_ENTRY_SELECTED_FIB (1 << 2)

19 u_char nexthop_num; /*Nexthop information.*/

20 u_char nexthop_active_num;21 u_char nexthop_fib_num;22 };

93e3ef9b3ca94f69293e948223078d88.gif

3、整个路由表的描述:

93e3ef9b3ca94f69293e948223078d88.gif

/*Routing table top structure.*/

structroute_table {struct route_node *top;/** Delegate that performs certain functions for this table.*/route_table_delegate_t*delegate;

unsignedlongcount;void *info; /*User data.*/};

93e3ef9b3ca94f69293e948223078d88.gif

route_table包含了一个二叉树结构来保存所有的路由前缀和下一跳路由表项,prefix结构保持了路由前缀的长度和值,用来做最长前缀匹配:

93e3ef9b3ca94f69293e948223078d88.gif

1 /*Each routing entry.*/

2 structroute_node {3 struct prefix p; /*Actual prefix of this radix.*/

4 struct route_table *table; /*Tree link.*/

5 struct route_node *parent;6 struct route_node *link[2];7 unsigned int lock; /*Lock of this radix*/

8 void *info; /*Each node of route.*/

9 void *aggregate; /*Aggregation.*/

10

11 #define l_left link[0]

12 #define l_right link[1]

13 };

93e3ef9b3ca94f69293e948223078d88.gif

呃,说好的mtire树呢? 好吧,我们不太可能把成千上万的路由表项塞给linux内核,够用就行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quagga和Zebra是两个开源的网络路由软件套件。Zebra是一个基于BSD授权的路由软件套件,提供了OSPF、BGP、RIP、RIPng等协议的实现。而Quagga则是Zebra的一个分支,目前由社区维护,支持更多的协议,包括IS-IS、OSPFv3、PIM、RIPng等。 下面我们来简要分析一下Quagga和Zebra源码结构: 1. Quagga Quagga的源码主要分为以下几个部分: - bgpd:BGP协议的实现。 - ospfd:OSPF协议的实现。 - ospf6d:OSPFv3协议的实现。 - ripd:RIP协议的实现。 - ripngd:RIPng协议的实现。 - isisd:ISIS协议的实现。 - pimd:PIM协议的实现。 - vtysh:用户交互界面。 其中,每个协议的实现都在对应的目录下,包括配置文件的解析、协议控制块的管理、路由表的维护等。而vtysh则是一个基于GNU Readline的交互式命令行界面,用于用户与Quagga的交互。 2. Zebra Zebra源码主要分为以下几个部分: - zebra路由守护进程,负责各个协议之间的协调和管理。 - lib:公共库,包括路由表、控制块、事件机制等。 - ospf:OSPF协议的实现。 - ospf6:OSPFv3协议的实现。 - bgp:BGP协议的实现。 - ripd:RIP协议的实现。 - ripng:RIPng协议的实现。 在Zebra中,路由表、控制块等公共部分的实现都在lib目录下,而各个协议的实现则在对应的目录下。 总体来说,Quagga和Zebra源码结构比较清晰,各个协议之间的代码实现相对独立,方便开发者进行二次开发和定制。同时,它们的协议实现也比较完善,可以满足不同场景下的路由需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值