quagga支持BGP-4,BGP-4+協議,支持多協議(mpls,isis,ospf等等)以及單播,組播路由的導入和分發。
具體的協議,這里就不附錄了,網絡上有很多資料,或者RFC。
協議源碼的學習基於前幾章的quagga源碼分析,所以剛接觸的朋友最好瀏覽一下quagga的通用框架以及通用路由處理流程。
好了,閑話少說,直奔主題才是最要緊的。
一、BGP初始化
初始化在bgp_main.c的main函數里開始,其他協議也類似,比如isis的main函數就在isis_main.c,這個嘛,簡單統一,通俗易懂。
main里最重要的初始化都在 void bgp_init(void) 這個函數里。
這里初始化了如下主要元素:
1、事件驅動的消息
2、bgp屬性的初始化:as_path,attr,community等的哈希表及其哈希函數
3、vty command
4、路由表的初始化
二、BGP路由表
1、數據結構:
1 struct bgp_table { 2 bgp_table_t type; 3 4 /* afi/safi of this table */ 5 afi_t afi; 6 safi_t safi; 7 8 int lock; 9 10 /* The owner of this 'bgp_table' structure. */ 11 struct peer *owner; 12 13 struct route_table *route_table; 14 };
bgp_table里字段定義:
type 表的類型 (BGP_TABLE_MAIN, BGP_TABLE_RSCLIENT)
afi 網絡類型(IPV4, IPV6)
safi 子網絡類型(SAFI_UNICAST,SAFI_MULTICAST,SAFI_RESERVED_3,SAFI_MPLS_VPN,SAFI_ENCAP)
lock 引用計數
owner 對等體的詳細描述
route_table 路由表項的集合,與之前zebra使用的是同一個數據結構
三、定時任務
bgp_scan_init函數定義2個定時任務:
1 void bgp_scan_init(void) { 2 zlookup = zclient_new(bm->master); 3 zlookup->sock = -1; 4 zlookup->t_connect = thread_add_event(bm->master, zlookup_connect, zlookup, 0); 5 6 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT; 7 bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT; 8 9 cache1_table[AFI_IP] = bgp_table_init(AFI_IP, SAFI_UNICAST); 10 cache2_table[AFI_IP] = bgp_table_init(AFI_IP, SAFI_UNICAST); 11 bgp_nexthop_cache_table[AFI_IP] = cache1_table[AFI_IP]; 12 13 bgp_connected_table[AFI_IP] = bgp_table_init(AFI_IP, SAFI_UNICAST); 14 15 cache1_table[AFI_IP6] = bgp_table_init(AFI_IP6, SAFI_UNICAST); 16 cache2_table[AFI_IP6] = bgp_table_init(AFI_IP6, SAFI_UNICAST); 17 bgp_nexthop_cache_table[AFI_IP6] = cache1_table[AFI_IP6]; 18 bgp_connected_table[AFI_IP6] = bgp_table_init(AFI_IP6, SAFI_UNICAST); 19 20 /* Make BGP scan thread. */ 21 bgp_scan_thread = thread_add_timer(bm->master, bgp_scan_timer, 22 NULL, bgp_scan_interval); 23 /* Make BGP import there. */ 24 bgp_import_thread = thread_add_timer(bm->master, bgp_import, NULL, 0); 25 }
bgp_scan_interval是可以通過命令配置修改的。
1 DEFUN(bgp_scan_time, 2 bgp_scan_time_cmd, 3 "bgp scan-time <5-60>", 4 "BGP specific commands\n" 5 "Configure background scanner interval\n" 6 "Scanner interval (seconds)\n") { 7 bgp_scan_interval = atoi(argv[0]); 8 9 if (bgp_scan_thread) { 10 thread_cancel(bgp_scan_thread); 11 bgp_scan_thread = 12 thread_add_timer(bm->master, bgp_scan_timer, NULL, bgp_scan_interval); 13 } 14 15 return CMD_SUCCESS; 16 }
默認的掃描間隔是60s,import間隔是15s,在thread_add_timer函數添加定時器任務的時候取當前的時間加上間隔時間,定時循環執行。
1 #define BGP_SCAN_INTERVAL_DEFAULT 60 2 #define BGP_IMPORT_INTERVAL_DEFAULT 15
quagga會定時的掃描路由表,檢查其中的路由表現的下一跳是否可達。bgp_scan函數來完成這個操作,通過向zserv查詢路由信息,來檢查合法性,從而更新路由或者收斂路由。
當然,在跟對等體交互時也會更新路由,這個主要bgp_update函數完成。