日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

开源路由软件zebra的命令存储原理及使用方法

發布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开源路由软件zebra的命令存储原理及使用方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ZZ FROM:?http://www.cnblogs.com/iTsihang/archive/2012/12/05/2783252.html


===============================================================================================================


zebra在設計命令格式的時候,將命令節點Node和命令Command分開,整個命令結構是一個樹狀的,如圖:?

??

? ? NODEn表示命令節點,CMDn表示具體的命令。在zebra的整個命令行設計當中,zebra用向量的概念將命令和節點連接起來,建立起隸屬關系。一個全局向量CMDVEC,指向整個命令結構,CMDVEC的每一個索引值都是一個具體的命令節點(如果有的話);在每個命令節點的結構中又存在各自的向量cmd_vector,該向量將指向隸屬于該節點的命令,cmd_vector中的每個索引值都是一個具體的命令(如果注冊的話)。于是,從最初的CMDVEC向量開始,程序就能“順藤摸瓜“找到任何一個已經注冊的命令。比如,程序調用某個方法,該方法對應的命令是CMD1,而該命令的調用是在NODEn這個節點下,那么自然而然,程序就能鎖定CMDVEC—>NODEn—>CMD1,實現一條匹配。

?

命令的注冊過程

? ? zebra要成功注冊一個命令,需要以下幾個步驟:1> 安裝一個節點。如果不需要新的命令節點,而使用zebra中自帶的節點,可省去這個步驟;2> 寫一條命令的實現;3> 將一條實現了的命令安裝到命令節點下。

? ? 介紹之前,有必要說明一下和命令相關的數據結構。

?

向量

1 /* struct for vector */ 2 struct _vector 3 { 4 unsigned int max; /* max number of used slot */ 5 unsigned int alloced; /* number of allocated slot */ 6 void **index; /* index to data */ 7 };

在zebra.h中定義,表示一個向量結構。該結構中,max表示目前使用的最大slot,alloced表示已經分配給該向量的最大slot數,max <= alloced。Index通過索引方式,存儲value。

?

命令節點

1 /* Node which has some commands and prompt string and configuration function pointer . */ 2 3 struct cmd_node 5 { 7 /* Node index. */ 9 enum node_type node; 11 /* Prompt character at vty interface. */ 13 char *prompt; 17 /* Is this node's configuration goes to vtysh ? */ 19 int vtysh; 23 /* Node's configuration write function */ 25 int (*func) (struct vty *); 29 /* Vector of this node's command list. */ 31 vector cmd_vector; 33 };

該結構在command.h中定義,用來表示一個命令節點,節點的類型由node_type枚舉指出,節點的標識字符由prompt表示,func表示該節點對應的操作方法,該節點下的命令由vector定義的cmd_vector表示。例如,在全局配置模式下,命令節點的定義可以是:

1 struct cmd_node config_node = 3 { 5 CONFIG_NODE, 7 "%s(config)# ", 9 1 11 };

?

命令

此外,command.h中還有一個重要的結構,就是cmd_element結構,該結構定義了一條命令的全部信息,定義如下:

1 /* Structure of command element. */ 3 struct cmd_element 5 { 7 char *string; /* Command specification by string. */ 9 int (*func) (struct cmd_element *, struct vty *, int, char **); 11 char *doc; /* Documentation of this command. */ 13 int daemon;                 /* Daemon to which this command belong. */ 15 vector strvec; /* Pointing out each description vector. */ 17 int cmdsize; /* Command index count. */ 19 char *config; /* Configuration string */ 21 vector subconfig; /* Sub configuration string */ 23 };

string 描述了命令的實現串,比如我要顯示某個配置信息:“show where are you from“;

func 則是實現string的具體方法;

doc 是string的解釋,zebra將string和doc 解析存儲,由strvec這個向量指向。

?

下面,我們逐步使用zebra。

?

安裝一個命令節點

zebra中安裝命令節點的接口:void install_node (struct cmd_node *node, int (*func) (struct vty *))

我們知道,整個zebra的框架是由一個向量指向一個節點,該節點又存在另一個向量,這個向量又有自己的存儲結構。從而將整個zebra的命令連接起來,起到提綱挈領的作用。zebra中由vector定義了一個全局向量,名為cmdvec,也就是上文說的CMDVEC。命令節點安裝的實質就是將一個cmd_node結構的地址,存儲到cmdvec中的一個未被使用的slot—index[i]里。

你可以將自己的命令安裝在zebra原帶的節點下,也可以添加自己新的節點,我以我的名字命名了一個新的節點。在command.c的73行定義:

1 struct cmd_node tsihang_node = 3 { 5 TSIHANG_NODE, 7 "%s(tsihang)# ", 9 1 11 };

將TSIHANG_NODE添加到node_type的CONFIG_NODE之后。然后在command.c的3115行,使用install_node將這個節點安裝到cmdvec中:install_node (&tsihang_node, NULL);

?

寫一條命令的實現方法

zebra實現命令的方法由command.h中的一個宏來實現

1 /* DEFUN for vty command interafce. */ 3 #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ 5 int funcname (struct cmd_element *, struct vty *, int, char **); \ 7 struct cmd_element cmdname = \ 9 { \ 11 cmdstr, \ 13 funcname, \ 15 helpstr \ 17 }; \ 19 int funcname \ 21 (struct cmd_element *self, struct vty *vty, int argc, char **argv)

這個宏很有意思,它表明了一個命令的結構,命令描述,命令的解釋,和命令的具體實現方法。編輯command.c文件,照著樣子寫一條命令實現方法。

例如,我實現的一個簡單方法:

1 DEFUN (tsihang_hello, 3 tsihang_hello_cmd, 5 "tsihang say hello", 7 "Greet\n" 9 "Greet to someone\n") 11 { 13 vty_out (vty, "Hello,you can do like this %s", VTY_NEWLINE); 15 return CMD_SUCCESS; 17 }

?

但是這樣還是不夠的,要進入tsihang_node節點還得靠一個觸發命令

1 //add by Tsihang for test cmmand 3 /* Tsihang command */ 5 DEFUN (tsihang_enable, 7 tsihang_enable_cmd, 9 "tsihang", 11 "Turn on privileged mode command\n") 13 { 15 vty->node = TSIHANG_NODE; 17 return CMD_SUCCESS; 19 }

?

安裝命令

命令的安裝實質是將一個cmd_element結構,存儲到cmd_node結構中的成員cmd_vec向量的一個未被使用的slot里。

調用接口

/* Install a command into a node. */

void install_element (enum node_type ntype, struct cmd_element *cmd)?,將剛才寫好的命令安裝到定義的節點下

在command.c中3192行添加

/* 為了進入自定義節點,需要安裝觸發命令 */

install_element(ENABLE_NODE, &tsihang_enable_cmd);

install_element(TSIHANG_NODE, &tsihang_hello_cmd);?

?

編譯,運行

編譯在我的博客:http://www.cnblogs.com/iTsihang/archive/2012/11/22/2783249.html? 中有介紹。

編譯完成后,進入zebra目錄,執行./zebra&,然后遠程登錄 telnet 127.0.0.1 2061 端口,zebra的密碼都在zebra.conf文件中,登錄后可使用。

進到tsihang節點下,運行命令:

1 Router(tsihang)#tsihang say hello 3 Hello, you can do like this 5 Router(tsihang)#

本測試例子下載:http://files.cnblogs.com/iTsihang/zebra-0.95a-t.tar.zip


轉載于:https://www.cnblogs.com/iplus/archive/2013/01/28/4467338.html

總結

以上是生活随笔為你收集整理的开源路由软件zebra的命令存储原理及使用方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。