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的事件中處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM