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

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

1、队列初始化:

  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 = ;
  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. }

第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 exported
  3. * as global here for test-rig code.
  4. */
  5. int rib_process_hold_time = ;

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

  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, long delay,
  6. debugargdef) {
  7. struct timeval trel;
  8.  
  9. assert(m != NULL);
  10.  
  11. if (delay) {
  12. trel.tv_sec = delay / ;
  13. trel.tv_usec = * (delay % );
  14. } else {
  15. trel.tv_sec = ;
  16. trel.tv_usec = ;
  17. }
  18.  
  19. return funcname_thread_add_timer_timeval(m, func, THREAD_BACKGROUND,
  20. arg, &trel, debugargpass);
  21. }

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)

  1. struct rib {
  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. };

3、整个路由表的描述:

  1. /* Routing table top structure. */
  2. struct route_table {
  3. struct route_node *top;
  4. /*
  5. * Delegate that performs certain functions for this table.
  6. */
  7. route_table_delegate_t *delegate;
  8. unsigned long count;
  9. void *info; /* User data. */
  10. };

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

  1. /* Each routing entry. */
  2. struct route_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[];
  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. };

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

quagga源码分析--路由信息处理zebra-rib的更多相关文章

  1. quagga源码分析--大内总管zebra

    zebra,中文翻译是斑马,于是我打开了宋冬野的<斑马,斑马>作为BGM来完成这个篇章,嘿嘿,小资一把! zebra姑且戏称它是quagga项目的大内总管. 因为它负责管理其他所有协议进程 ...

  2. MVC源码分析 - 路由匹配

    上一篇 说到了路由事件注册以及路由表的生成, 前面 也解析到了, 管道事件的建立, 那么接下来, 肯定就是要调用执行这些事件了, 这些就不表了, 我已经得到我想要的部分了, 接下来, 在执行这些管道事 ...

  3. quagga源码分析--内核通信netlink

    Linux操作系统中当CPU处于内核状态时,可以分为有用户上下文的状态和执行硬件.软件中断两种.其中当处于有用户上下文时,由于内核态和用户态的内 存映射机制不同,不可直接将本地变量传给用户态的内存区: ...

  4. quagga源码分析--通用库command

    quagga作为一个路由器软件,自然要提供人机接口. quagga提供snmp管理接口,而且,自然就会有对应的命令行管理格式,当然一般路由软件不会提供界面形式的,也许有webui,然而quagga并没 ...

  5. quagga源码分析--通用库thread

    quagga是开源路由器软件,提供的用户界面与思科,华为的路由器的人机接口几乎一致,非常有学习价值,尤其是开源的协议代码,简直亮瞎了我的小眼睛. quagga的介绍,我就不赘述了,有兴趣的可以找度娘或 ...

  6. quagga源码学习--BGP协议的初始化

    quagga支持BGP-4,BGP-4+协议,支持多协议(mpls,isis,ospf等等)以及单播,组播路由的导入和分发. 具体的协议,这里就不附录了,网络上有很多资料,或者RFC. 协议源码的学习 ...

  7. illuminate/routing 源码分析之注册路由

    我们知道,在 Laravel 世界里,外界传进来一个 Request 时,会被 Kernel 处理并返回给外界一个 Response.Kernel 在处理 Request 时,会调用 illumina ...

  8. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  9. flask框架(三)——路由系统route转换成add_url_rule及源码分析

    这节我们不用@app.route来写路由,而是通过add_url_rule 传统写法  (<int:nid>传递int类型参数,endpoint是取别名) @app.route('/det ...

随机推荐

  1. JavaScript 多级联动浮动(下拉)菜单 (第二版)

    JavaScript 多级联动浮动(下拉)菜单 (第二版)   上一个版本(第一版请看这里)基本实现了多级联动和浮动菜单的功能,但效果不是太好,使用麻烦还有些bug,实用性不高.这次除了修改已发现的问 ...

  2. 如何通过js给QQ好友发送信息

    一般我们在做页面活动的时候可能会碰到点击一个按钮把一些相关的信息通过QQ发送给你的好友,这种信息推送的功能该如何实现呢!下面我来介绍下使用方法! 代码如下: <!DOCTYPE HTML> ...

  3. 【转】android中TextAppearanceSpan的使用

    android中TextAppearanceSpan的使用 Posted on April 17, 2011 在android中如何想word中一样对文字进行丰富的风格设置呢? TextAppeara ...

  4. redmine的邮件配置

    redmine的邮件配置 2012-01-04 18:09:21|  分类: 默认分类|举报|字号 订阅     redmine里要用到邮件通知,本来以为很是简单,网上也有许多教程,谁知忙活了一下午, ...

  5. 谈谈Oracle dba_free_space

    谈谈Oracle dba_free_space 博客分类: ORACLE管理 OracleSQLC#C++C  顾名思义,dba_free_space指的是Oracle还有多少表空间剩余空间,其视图结 ...

  6. JavaScript闭包小窥

    众所周知,JavaScript没有块级作用域,只有函数作用域.那就意味着定义在函数中的参数和变量在函数外部是不可见的,而在一个函数内部任何位置定义的变量,在该函数内部任何地方都可见.这带来的好处是内部 ...

  7. NLP startup material

    The Association for Computational Linguistics(ACL,URL:http://aclweb.org/) Computational Linguistics( ...

  8. DOM(一)

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. ASP.NET MVC4中使用NHibernate

    ASP.NET MVC4中使用NHibernate 1:下载安装NHibernate 打开 VS 2012新建一个 MVC4项目. 在项目名称上右击选择Manage NuGet Packages.你会 ...

  10. 对于vijos11.2模拟赛

    特意起了个傻逼标题,只是想提醒一下自己以后不要犯逗(所以应该没有什么神犇点进来吧?) T1,T3 当场写的时候就觉得是不可写的,看了题解之后还是觉得不可写,人弱没办法.到了这个时候也懒得管这么难的东西 ...