quagga源码学习--BGP协议的初始化
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函数完成。