quagga源码学习--BGP协议路由更新

BGP的核心就是交换路由,所以关键的部分还是在路由的更新与撤销上面,这之间包含了冗长的属性,community等等处理过程,不做详述。

bgp_read函数是路由更新的事件处理函数,在收到BGP_MSG_UPDATE消息的时候开始调用bgp_update_receive函数处理。

1 switch (i) {
2         case NLRI_UPDATE:
3         case NLRI_MP_UPDATE:
4             nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG, &nlris[i]);
5             break;
6         case NLRI_WITHDRAW:
7         case NLRI_MP_WITHDRAW:
8             nlri_ret = bgp_nlri_parse(peer, NULL, &nlris[i]);
9         }

上面是更新路由与撤销路由。比如在cli输入clear ip bgp 命令的时候会撤销路由。

nlri是(network layer reachable infomation)的缩写。

在bgp_nlri_parse里对bgp UPDATE消息内容进行处理,遍历消息内容里的全部路由前缀,开始bgp_update调用。

1 /* Normal process. */
2         if (attr)
3             ret = bgp_update(peer, &p, attr, packet->afi, packet->safi,
4                              ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
5         else
6             ret = bgp_withdraw(peer, &p, attr, packet->afi, packet->safi,
7                                ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);

在bgp_update中对本节点以及所有的邻居的路由信息都进行更新,主要的更新是在bgp_process函数里。

1 switch (bgp_node_table(rn)->type) {
2     case BGP_TABLE_MAIN:
3         work_queue_add(bm->process_main_queue, pqnode);
4         break;
5     case BGP_TABLE_RSCLIENT:
6         work_queue_add(bm->process_rsclient_queue, pqnode);
7         break;
8     }

可以看到,最后都是在工作队列里进行更新。对应初始化的时候设置的工作函数:

1     bm->process_main_queue->spec.workfunc = &bgp_process_main;
2     bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
3     bm->process_main_queue->spec.max_retries = 0;
4     bm->process_main_queue->spec.hold = 50;
5
6     bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
7     bm->process_rsclient_queue->spec.del_item_data = &bgp_processq_del;
8     bm->process_rsclient_queue->spec.max_retries = 0;
9     bm->process_rsclient_queue->spec.hold = 50;

对本节点(即服务端),在bgp_process_main里最终发送给了zserv。

1 zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *)p, &api);

对于邻居(即通过neighbor命令配置的),在bgp_process_rsclient中分别如下处理

如果是添加或者更新,则添加到fifo队列中:

1 /* Add new advertisement to advertisement attribute list. */
2     bgp_advertise_add(adv->baa, adv);
3
4     FIFO_ADD(&peer->sync[afi][safi]->update, &adv->fifo);

如果是撤销路由,则:

1 /* Add to synchronization entry for withdraw announcement.  */
2         FIFO_ADD(&peer->sync[afi][safi]->withdraw, &adv->fifo);
3
4         /* Schedule packet write. */
5         BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);

都是在thread任务调度的bgp_write的事件中处理。

时间: 02-02

quagga源码学习--BGP协议路由更新的相关文章

quagga源码学习--BGP协议创建对等体

现有的路由协议都是通过分布式协议逐个配置协商运行的,协议协议,一个就不需要协议咯,至少2个才能够协议着做事情嘛,不过呢,这样就出现网元过多配置困难的问题,对网管软件要求也越来越高, SDN或许可能改变这个局面,但不管软件如何定义,报文还是在一个一个网络节点传输的,所以我们看到quagga这样多的传统网络配置命令不要觉得繁琐,不配置的话,协议不会工作哦. 嗯,这章的主题是创建对等体,就是通过配置命令来完成的. "neighbor peer remote-as asn" router bg

quagga源码学习--BGP协议对等体的状态机

创建完bgp peer之后,就要bgp start了,不然费那么大劲创建出来不做事情就销毁了,就很尴尬了. 那么对等体一旦start起来,就会进入各自的状态,在不同的状态下处理各自的事件消息. 下面列举一些状态和事件的集合: 1 /* BGP finite state machine status. */ 2 #define Idle 1 3 #define Connect 2 4 #define Active 3 5 #define OpenSent 4 6 #define OpenConfi

Redis源码学习:字符串

Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串,还用来当做缓冲区,例如AOF缓冲区或输入缓冲区等.如下所示,整数len和free分别表示buf数组中已使用的长度和剩余可用的长度,buf是一个原生C字符串,以\0结尾. sds就是sdshdr中char buf[]的别名,后面能看到,各种操作函数的入参和返回值都是sds而非sdshdr.那sdshd

HSQLDB源码学习——数据库安装启动及JDBC连接

HSQLDB 是一个轻量级的纯Java开发的开放源代码的关系数据库系统.因为HSQLDB的轻量(占用空间小),使用简单,支持内存运行方式等特点,HSQLDB被广泛用于开发环境和某些中小型系统中. 在http://sourceforge.net/projects/hsqldb/files/下载了HSQLDB 1.8.0版本.把下载的zip文件解压缩至任意目录例如c:\hsqldb1.8便完成安装. hsqldb有四种运行模式: 一.内存(Memory-Only)模式:所有数据都在内存里操作.应用程

tomcat源码学习(2)  关于apache digest

好久不写博文,罪过罪过.因为最近公司比较忙加上琐事有点多,所以隔了好久才来更新博文. apache digest本来是struts2框架中来加载xml文件并实例化对象的一个jar包,后来使用的越来越多. 我们都知道tomcat的conf文件夹下有一个server.xml配置文件,我们经常会其中的来进行配置以来运行一个java web项目,也经常修改中的port属性以来实现修改tomcat监听的端口.其实每个标签基本上都对应着一个对象,那tomcat是如何将这些对象实例化到java 虚拟机的运行内

lua源码学习(一)lua的c api外围实现

工作后,整个人已经比较松懈了.虽然一直在看lua的源码,但是一直是比较零碎的时间,没有系统的整理,所以还是收获不多.因为最近工作也不是很忙了,就想整理下lua的源码学习的笔记,加深下印象,并分享给大家. 先说下这系列bolg我会每周更新2-3篇,没有顺序的 这些文章都是自己的浅薄的理解,有什么错误,还请各位拍砖赐教. 1.关于c语言函数的声明 相信大家都知道接口的重要,在lua中,如果要调用c语言的函数,就必须要有一个统一的函数声明: typedef int (*lua_CFunction) (

JDK源码学习LinkedList

LinkedList是List接口的子类,它底层数据结构是双向循环链表.LinkedList还实现了Deque接口(double-end-queue双端队列,线性collection,支持在两端插入和移除元素).所以LinkedList既可以被当作双向链表,还可以当做栈.队列或双端队列进行操作.文章目录如下: 1.LinkedList的存储实现(jdk 1.7.0_51) 2.LinkedList的读取实现 3.LinkedList的性能分析 下面我们进入正题,开始学习LinkedList. L

nginx源码学习资源

http://www.cnblogs.com/yjf512/archive/2012/06/13/2548515.html 2012-06-13 21:32 by 轩脉刃, 26499 阅读, 5 评论, 收藏, 编辑 nginx源码学习是一个痛苦又快乐的过程,下面列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源码,可以从nginx官方网站下载一份最新的. 看了nginx源码,发现这是一份完全没有注释,完全没有配置文档的代码. 现在你最希望要的是一份注释版的nginx源码,

Java多线程之JUC包:ReentrantReadWriteLock源码学习笔记

若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/go2sea/p/5634701.html ReentrantLock提供了标准的互斥操作,但在应用中,我们对一个资源的访问有两种方式:读和写,读操作一般不会影响数据的一致性问题.但如果我们使用ReentrantLock,则在需要在读操作的时候也独占锁,这会导致并发效率大大降低.JUC包提供了读写锁ReentrantReadWriteLock,使得读写锁分离,在上述情