1) zebra是很有名的linux下的開源路由軟件項目,代碼寫的非常漂亮,模塊化,很清晰的結構。 關於軟件的框架部分就不說了,zebra 官方網站上已經有詳細的解釋了,簡單的來說:zebra作爲一個守護進程來維護linux路由信息,其他模塊rip, bgp 和這個守護進程通過消息通信來更新和獲取路由信息。
2) 項目主要是用到了RIP協議功能
3) 每一個模塊實際上是一個單進程的工作方式,在進程中,輪流執行thread塊,看上去是併發在運行;每一個模塊都有一個master結構,這個master結構維護了幾個thread list,有 event, read ,write等;當有需要的時候,每個thread塊結構加入到相應的list中去,進而在主進程會不斷的poll來執行list中的每一個thread塊
4) command list, 本質上是函數指針,關鍵性的代碼
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
int funcname (struct cmd_element *, struct vty *, int, char **); \
struct cmd_element cmdname = \
{ \
cmdstr, \
funcname, \
helpstr \
}; \
int funcname \
(struct cmd_element *self, struct vty *vty, int argc, char **argv)
當讀取輸入的命令時,這個命令字符串可能來自於用戶輸入,也可能來自於配置文件,根據命令的字符串信息來匹配到相應的command list中的command node,每一個command node都會知道一個函數指針,調用這個函數就會執行相應的命令了
5)工作過程,首先zebra模塊啓動,其次啓動相應的路由協議模塊,我們啓動了RIP模塊;在啓動RIP模塊的時候指定了配置文件,配置文件的產生是根據當前設備的wan連接狀態產生了,例如
interface br0
router rip
redistribute kernel
redistribute connected
redistribute static
network br0
interface br0
ip rip send version 2
ip rip receive version 2
interface ipoa0
router rip
redistribute kernel
redistribute connected
redistribute static
network ipoa0
interface ipoa0
ip rip send version 2
ip rip receive version 2
顯然我們設備有一個br0的橋接的interface,還有一個ipoa0的wan連接,rip模塊在解析配置文件的時候會依次執行每一行,每一行實際上就是一條命令;
例如, “router rip”
對應到command list中的“router_rip”函數,代碼中它是如下定義的
DEFUN (router_rip,
router_rip_cmd,
"router rip",
"Enable a routing process\n"
"Routing Information Protocol (RIP)\n")
這個DEFUN的定義在以上已經提到了。那個函數做了什麼呢,其實很簡單實際上就是創建了socket,根據RIP協議的RFC文檔,它監聽了520端口;並且創建了兩個thread塊;
rip_event ( RIP_READ, rip->sock );
rip_event ( RIP_UPDATE_EVENT, 1 );
這兩個線程並沒有真正的創建,只是master的tread list中,這樣RIP進程會依次執行
/* Execute each thread. */
while (thread_fetch (master, &thread))
thread_call (&thread);
6)和zebra模塊通信,當RIP執行redistribute kernel命令的時候實際上是給zebra發了一個消息,因爲最終的路由信息是zebra這個守護進程維護的,消息的格式是有定義的,
int ret;
struct stream *s;
s = stream_new (ZEBRA_MAX_PACKET_SIZ);
/* Total length of the messages. */
stream_putw (s, 4);
stream_putc (s, command);
stream_putc (s, type);
ret = writen (sock, s->data, 4);
stream_free (s);
struct stream 就是消息的定義了。
實際上模塊間的通信方式可以是tcp/udp通信也是unix socket通信,這個是可以由宏定義了,搞清楚這些之後,剩下的就是對協議的理解,以及對linux網絡編程的掌握了。