Chinaunix首页 | 论坛 | 博客
  • 博客访问: 389199
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-10 08:38
文章分类
文章存档

2016年(32)

2015年(48)

我的朋友

分类: LINUX

2015-07-22 15:20:45

 

Zebra-VTYSH源码分析和改造(序)

 1811人阅读 评论(0) 收藏 举报

最近公司一网络产品需要在WEB和SNMP的基础上添加CLI接口。


本身CLI(Command Line Interface)在产品中借助某芯片有简单ssdk_sh,由于客户要求CLI要想Cisco那样。(不知何故,特别指出并不看重web和snmp,只看重CLI)

只好研究通用的zebra-vtysh。


1. Zebra是一个路由软件包,提供基于TCP/IP路由服务,支持RIPv1, RIPv2, RIPng, OSPFv2, OSPFv3, BGP- 4, 和 BGP-4+等众多路由协议。Zebra还支持BGP特性路由反射器(Route Reflector)。除了传统的 IPv4路由协议,Zebra也支持IPv6路由协议。如果运行的SNMP守护进程(需要ucd-snmp)支持SMUX协 议,Zebra还能支持路由协议MIBs。

其中,出现的各种协议,不懂的google。


2. 其次zebra-vtysh是一开源软件,可以从官网上下载(目前最高版本是zebra-0.95a.tar.gz)。


具体怎么安装可以google下就可以。


但是关于zebra源码的分析就很少了,希望在这里开始我的源码和改造之路,和大家一起分享。






1. Zebra 功能认识

ZEBRA 提供了一个类Cisco命令行的分级多用户命令解析引擎--VTY(Virtual Terminal)。它是类似于Linux Shell的虚拟终端接口,负责对访问的安全验证、数据缓冲、命令解析、模式切换和命令调用。

用户通过VTYSH的每一次接口访问都会发起一个对应的VTY。VTY会根据用户优先级初始化并挂载相应的命令集Command Node。Command Node中以链表的形式包含了该用户可以访问和使用的Command。

用户通过各种接口访问VTY,VTY解析用户的每个命令,并且通过命令集链表找到并执行Command相应函数。这样,通过访问VTY实现基于命令集的管理功能。


2. Zebra 架构

Zebra采用模块化的架构,,整个程序由一系列的守护进程构成,每个路由协议都有自己单独的路由处理进程,同时,它提供一个管理内核路由表的zebra 守护进程。路由处理程序通过zebra 守护程序管理内核路由表。

由图示可知,在Zebra中,总共有五个路由守护进程,和一个管理进程。这些路由进程可以和管理进程分布在不同的机器上,每一个进程可以分别监听从不同的端口来的VTY连接。

3. 编译Zebra为我所用

一般的路由产品都可以拿来Zebra稍加改动就可以使用了。如果你只需要VTY连接功能,通过接口增、改、删命令的话,Zebra是支持模块的删除和屏蔽的。

比如只需要VTY,那么你编译的时候可以在congfigure的时候加上如下参数就可以了。

...

cd ../zebra-vtysh && (test -e config.status ||(touch config.status && ./configure --disable-ipv6 --disable-bgpd --disable-ripngd  --disable-ospf6d --disable-bgp-announce --enable-vtysh --disable-ospfd --disable-ripd --disable-zebra --prefix=/ --with-cflags="-O2 -Wall" --build=i386 --host=mips-linux --target=mips)) &&

...

(其中,config.status是configure的状态记录信息,以备下次使用)


这样,编译完zebra后,就可以运行vtysh了,查看它的各种模式(下篇文章会讲),就可以开始你的快乐之旅了。


参考:http://







分析Zebra-VTYSH的源码,首先从main函数开始,在ztysh-main.c中找到main函数,来进一步分析流程执行如下图所示:

 

在平时的使用中我们会发现,配置的时候有很多的视图(View),每个视图中有不同的命令可供用户输入进行配置。

这里,根据源码,视图可以认为是Node,而每一个命令称为element,他们之间的结构如下图所示:

 

 

如图中所示,用到的数据结构如下:

 

  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. };  
  8. /* Node which has some commands and prompt string and configuration 
  9.    function pointer . */  
  10. struct cmd_node   
  11. {  
  12.   /* Node index. */  
  13.   enum node_type node;        
  14.   
  15.   /* Prompt character at vty interface. */  
  16.   char *prompt;           
  17.   
  18.   /* Is this node's configuration goes to vtysh ? */  
  19.   int vtysh;  
  20.     
  21.   /* Node's configuration write function */  
  22.   int (*func) (struct vty *);  
  23.   
  24.   /* Vector of this node's command list. */  
  25.   vector cmd_vector;      
  26. };  
  27.   
  28. /* Structure of command element. */  
  29. struct cmd_element   
  30. {  
  31.   char *string;         /* Command specification by string. */  
  32.   int (*func) (struct cmd_element *, struct vty *, intchar **);  
  33.   char *doc;            /* Documentation of this command. */  
  34.   int daemon;                   /* Daemon to which this command belong. */  
  35.   vector strvec;        /* Pointing out each description vector. */  
  36.   int cmdsize;          /* Command index count. */  
  37.   char *config;         /* Configuration string */  
  38.   vector subconfig;     /* Sub configuration string */  
  39. };  
  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. };  
  8. /* Node which has some commands and prompt string and configuration 
  9.    function pointer . */  
  10. struct cmd_node   
  11. {  
  12.   /* Node index. */  
  13.   enum node_type node;        
  14.   
  15.   /* Prompt character at vty interface. */  
  16.   char *prompt;           
  17.   
  18.   /* Is this node's configuration goes to vtysh ? */  
  19.   int vtysh;  
  20.     
  21.   /* Node's configuration write function */  
  22.   int (*func) (struct vty *);  
  23.   
  24.   /* Vector of this node's command list. */  
  25.   vector cmd_vector;      
  26. };  
  27.   
  28. /* Structure of command element. */  
  29. struct cmd_element   
  30. {  
  31.   char *string;         /* Command specification by string. */  
  32.   int (*func) (struct cmd_element *, struct vty *, intchar **);  
  33.   char *doc;            /* Documentation of this command. */  
  34.   int daemon;                   /* Daemon to which this command belong. */  
  35.   vector strvec;        /* Pointing out each description vector. */  
  36.   int cmdsize;          /* Command index count. */  
  37.   char *config;         /* Configuration string */  
  38.   vector subconfig;     /* Sub configuration string */  
  39. };  


 

下面我们所要做的事情就是在node和element中添加我们自己的命令,如果一切顺利,稍加处理就可以在图一中的最后一步也就是loop循环中的vtysh_execute函数中来实现我们的执行过程了。





一 视图介绍

由上面几篇文章分析可见,所有的命令都是包含在node中的,根据Cisco或者H3常见路由器或者交换机的CLI格式可见,一个node就对应着一个视图(View)。常用的视图包括:普通视图,管理视图,文件系统视图,配置视图,以及接口配置视图和VLAN视图等。

在Zebra-VTYSH源码中,实现了的有Enable视图和配置视图。如下图所示:

  1. / # vtysh   
  2.   
  3. Copyright 2010-2011 IBM Co., Ltd.  
  4.   
  5. CLI> enable   
  6. CLI#   
  7.   clear        Reset functions  
  8.   configure    Configuration from vty interface  
  9.   copy         Copy from one file to another  
  10.   debug        Debugging functions (see also 'undebug')  
  11.   disable      Turn off privileged mode command  
  12.   end          End current mode and down to previous mode  
  13.   exit         Exit current mode and down to previous mode  
  14.   list         Print command list  
  15.   no           Negate a command or set its defaults  
  16.   ping         send echo messages  
  17.   quit         Exit current mode and down to previous mode  
  18.   show         Show running system information  
  19.   start-shell  Start UNIX shell  
  20.   telnet       Open a telnet connection  
  21.   terminal     Set terminal line parameters  
  22.   traceroute   Trace route to destination  
  23.   undebug      Disable debugging functions (see also 'debug')  
  24.   write        Write running configuration to memory, network, or terminal  
  25. CLI# configure terminal   
  26. CLI(config)#   
  27.   access-list    Add an access list entry  
  28.   bgp            BGP information  
  29.   debug          Debugging functions (see also 'undebug')  
  30.   device-config  Device configuration  
  31.   dump           Dump packet  
  32.   enable         Modify enable password parameters  
  33.   end            End current mode and down to previous mode  
  34.   exit           Exit current mode and down to previous mode  
  35.   hostname       Set system's network name  
  36.   interface      Select an interface to configure  
  37.   ip             IP information  
  38.   ipv6           IPv6 information  
  39.   key            Authentication key management  
  40.   list           Print command list  
  41.   log            Logging control  
  42.   no             Negate a command or set its defaults  
  43.   password       Assign the terminal connection password  
  44.   route-map      Create route-map or enter route-map command mode  
  45.   router         Enable a routing process  
  46.   system-config  System and management configuration  
  47.   username  
  48.   write          Write running configuration to memory, network, or terminal  
  49. CLI(config)# system-config   
  50. CLI(config-system)#   
  51.   access                   Set CPE access ND flag  
  52.   admin-idle-time          Set system idle time  
  53.   admin-psw                Set system administrator password  
  54.   admin-username           Set system administrator username  
  55.   connection-mode          Set network connection mode : static and dynamic  
  56.   datetime                 Set date time (format:2000-01-01 00:00:00)  
  57.   default-gateway          Set system's network default gateway  
  58.   dns-server-1             Set system network DNS server 1  
  59.   dns-server-2             Set system network DNS server 2  
  60.   exit                     Exit current mode and down to previous mode  
  61.   factory-defaults         Restore ALL configure to factory default values( 0: reset all 1: reset with network parameters unchanged)  
  62.   hostname                 Set system's network name  
  63.   image-upgrade            Upgrade image via ftp method  
  64.   ip                       Set system ip address and netmask  
  65.   list                     Print command list  
  66.   managment-ip-range       Set management IP range and netmask  
  67.   managment-ip-range-flag  Set management IP range service flag  
  68.   mgr-vlan-id              Set management VLAN ID  
  69.   ntpserver                Set NTP server  
  70.   quit                     Exit current mode and down to previous mode  
  71.   reset                    Reset system  
  72.   snmp-refresh-time        Set SNMP service refresh time cycle  
  73.   snmp-rwcommunicty        Set SNMP read/write community  
  74.   snmp-service             Set SNMP service enable or disable  
  75.   snmp-trap-ip1            Set SNMP trap ip 1 address  
  76.   snmp-trap-ip2            Set SNMP trap ip 2 address  
  77.   snmp-trap1-ip-flag       Set SNMP trap ip 1 service flag(enable/disable)  
  78.   snmp-trap2-ip-flag       Set SNMP trap ip 2 service flag(enable/disable)  
  79.   ssh                      Set ssh service port and timeout values  
  80.   ssh-service              Set ssh service flag  
  81.   telnet                   Set telnet PORT  
  82.   telnet-service           Set telnet service flag  
  83.   timesync                 Set time sync service flag  
  84.   timezone                 Set time zone (0:ShangHai,1:ChongQing)  
  85. CLI(config-system)# quit  
  86. CLI(config)# device-config   
  87. CLI(config-device)#   
  88.   exit                       Exit current mode and down to previous mode  
  89.   list                       Print command list  
  90.   port-mirror-analysis-port  Device configuration: Set analysis port(1: eth1 2: eth2)  
  91.   port-mirror-flag           Device configuration: Enable or disable port mirror service(0:disable,1:enable)  
  92.   port-mirror-packet         Device configuration: Set packet type to be mirrored(1:Import & Export 2: Import 3: Export)  
  93.   port-mirror-port           Device configuration:Set port to be mirrored  
  94.   port1-rate                 Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.  
  95.   port2-rate                 Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.  
  96.   quit                       Exit current mode and down to previous mode  
  97. CLI(config-device)#   
  98. CLI(config-device)#  
  1. / # vtysh   
  2.   
  3. Copyright 2010-2011 IBM Co., Ltd.  
  4.   
  5. CLI> enable   
  6. CLI#   
  7.   clear        Reset functions  
  8.   configure    Configuration from vty interface  
  9.   copy         Copy from one file to another  
  10.   debug        Debugging functions (see also 'undebug')  
  11.   disable      Turn off privileged mode command  
  12.   end          End current mode and down to previous mode  
  13.   exit         Exit current mode and down to previous mode  
  14.   list         Print command list  
  15.   no           Negate a command or set its defaults  
  16.   ping         send echo messages  
  17.   quit         Exit current mode and down to previous mode  
  18.   show         Show running system information  
  19.   start-shell  Start UNIX shell  
  20.   telnet       Open a telnet connection  
  21.   terminal     Set terminal line parameters  
  22.   traceroute   Trace route to destination  
  23.   undebug      Disable debugging functions (see also 'debug')  
  24.   write        Write running configuration to memory, network, or terminal  
  25. CLI# configure terminal   
  26. CLI(config)#   
  27.   access-list    Add an access list entry  
  28.   bgp            BGP information  
  29.   debug          Debugging functions (see also 'undebug')  
  30.   device-config  Device configuration  
  31.   dump           Dump packet  
  32.   enable         Modify enable password parameters  
  33.   end            End current mode and down to previous mode  
  34.   exit           Exit current mode and down to previous mode  
  35.   hostname       Set system's network name  
  36.   interface      Select an interface to configure  
  37.   ip             IP information  
  38.   ipv6           IPv6 information  
  39.   key            Authentication key management  
  40.   list           Print command list  
  41.   log            Logging control  
  42.   no             Negate a command or set its defaults  
  43.   password       Assign the terminal connection password  
  44.   route-map      Create route-map or enter route-map command mode  
  45.   router         Enable a routing process  
  46.   system-config  System and management configuration  
  47.   username  
  48.   write          Write running configuration to memory, network, or terminal  
  49. CLI(config)# system-config   
  50. CLI(config-system)#   
  51.   access                   Set CPE access ND flag  
  52.   admin-idle-time          Set system idle time  
  53.   admin-psw                Set system administrator password  
  54.   admin-username           Set system administrator username  
  55.   connection-mode          Set network connection mode : static and dynamic  
  56.   datetime                 Set date time (format:2000-01-01 00:00:00)  
  57.   default-gateway          Set system's network default gateway  
  58.   dns-server-1             Set system network DNS server 1  
  59.   dns-server-2             Set system network DNS server 2  
  60.   exit                     Exit current mode and down to previous mode  
  61.   factory-defaults         Restore ALL configure to factory default values( 0: reset all 1: reset with network parameters unchanged)  
  62.   hostname                 Set system's network name  
  63.   image-upgrade            Upgrade image via ftp method  
  64.   ip                       Set system ip address and netmask  
  65.   list                     Print command list  
  66.   managment-ip-range       Set management IP range and netmask  
  67.   managment-ip-range-flag  Set management IP range service flag  
  68.   mgr-vlan-id              Set management VLAN ID  
  69.   ntpserver                Set NTP server  
  70.   quit                     Exit current mode and down to previous mode  
  71.   reset                    Reset system  
  72.   snmp-refresh-time        Set SNMP service refresh time cycle  
  73.   snmp-rwcommunicty        Set SNMP read/write community  
  74.   snmp-service             Set SNMP service enable or disable  
  75.   snmp-trap-ip1            Set SNMP trap ip 1 address  
  76.   snmp-trap-ip2            Set SNMP trap ip 2 address  
  77.   snmp-trap1-ip-flag       Set SNMP trap ip 1 service flag(enable/disable)  
  78.   snmp-trap2-ip-flag       Set SNMP trap ip 2 service flag(enable/disable)  
  79.   ssh                      Set ssh service port and timeout values  
  80.   ssh-service              Set ssh service flag  
  81.   telnet                   Set telnet PORT  
  82.   telnet-service           Set telnet service flag  
  83.   timesync                 Set time sync service flag  
  84.   timezone                 Set time zone (0:ShangHai,1:ChongQing)  
  85. CLI(config-system)# quit  
  86. CLI(config)# device-config   
  87. CLI(config-device)#   
  88.   exit                       Exit current mode and down to previous mode  
  89.   list                       Print command list  
  90.   port-mirror-analysis-port  Device configuration: Set analysis port(1: eth1 2: eth2)  
  91.   port-mirror-flag           Device configuration: Enable or disable port mirror service(0:disable,1:enable)  
  92.   port-mirror-packet         Device configuration: Set packet type to be mirrored(1:Import & Export 2: Import 3: Export)  
  93.   port-mirror-port           Device configuration:Set port to be mirrored  
  94.   port1-rate                 Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.  
  95.   port2-rate                 Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.  
  96.   quit                       Exit current mode and down to previous mode  
  97. CLI(config-device)#   
  98. CLI(config-device)#  

如果想要添加自己的命令,可以在原有的视图上增加(也就是在原有的node中增加commands),或者新开自己的视图,然后在新视图中添加自己的commands。

二 添加命令

进入vtysh目录中,查看vtysh_main.c文件的main函数,也就是和vtysh初始化相关的一切都在这里,基本上在这里可以完成你需要的一些基本命令。

在函数vtysh_init_vty()中,有个

  1. /* Initialize command interface. Install basic nodes and commands. */  
  2. Void cmd_init (int terminal)  
  1. /* Initialize command interface. Install basic nodes and commands. */  
  2. Void cmd_init (int terminal)  


 

的函数,就是负责初始化command接口,安装node和命令的。

比如你就可以添加自己的视图如下:

  1. /*Added by xyang*/  
  2.     install_element (CONFIG_NODE, &vtysh_sysconfig_cmd);  
  3.     install_element (CONFIG_NODE, &vtysh_devconfig_cmd);  
  1. /*Added by xyang*/  
  2.     install_element (CONFIG_NODE, &vtysh_sysconfig_cmd);  
  3.     install_element (CONFIG_NODE, &vtysh_devconfig_cmd);  


 

(其中,安装的system和device配置的视图)

  1. /*Added by xyang 
  2. * system config node* 
  3. */  
  4. DEFUN (system_config,  
  5.        vtysh_sysconfig_cmd,  
  6.        "system-config",  
  7.        SYS_CFG_STR  
  8.        "\n")  
  9. {    
  10.   //vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);  
  11.   
  12.    vty->node = SYSCONFIG_NODE;  
  13.   
  14.   return CMD_SUCCESS;  
  15. }  
  16. DEFUN (device_config,  
  17.        vtysh_devconfig_cmd,  
  18.        "device-config",  
  19.        DEV_CFG_STR  
  20.        "\n")  
  21. {    
  22.     
  23.   //vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);  
  24.   
  25.    vty->node = DEVCONFIG_NODE;  
  26.   
  27.   return CMD_SUCCESS;  
  28. }  
  29. DEFUN定义为:  
  30. /* DEFUN for vty command interafce. Little bit hacky ;-). */  
  31. #define DEFUN(funcname, cmdname, cmdstr, helpstr) \  
  32.   int funcname (struct cmd_element *, struct vty *, intchar **); \  
  33.   struct cmd_element cmdname = \  
  34.   { \  
  35.     cmdstr, \  
  36.     funcname, \  
  37.     helpstr \  
  38.   }; \  
  39.   int funcname \  
  40.   (struct cmd_element *self, struct vty *vty, int argc, char **argv)  
  1. /*Added by xyang 
  2. * system config node* 
  3. */  
  4. DEFUN (system_config,  
  5.        vtysh_sysconfig_cmd,  
  6.        "system-config",  
  7.        SYS_CFG_STR  
  8.        "\n")  
  9. {    
  10.   //vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);  
  11.   
  12.    vty->node = SYSCONFIG_NODE;  
  13.   
  14.   return CMD_SUCCESS;  
  15. }  
  16. DEFUN (device_config,  
  17.        vtysh_devconfig_cmd,  
  18.        "device-config",  
  19.        DEV_CFG_STR  
  20.        "\n")  
  21. {    
  22.     
  23.   //vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);  
  24.   
  25.    vty->node = DEVCONFIG_NODE;  
  26.   
  27.   return CMD_SUCCESS;  
  28. }  
  29. DEFUN定义为:  
  30. /* DEFUN for vty command interafce. Little bit hacky ;-). */  
  31. #define DEFUN(funcname, cmdname, cmdstr, helpstr) \  
  32.   int funcname (struct cmd_element *, struct vty *, intchar **); \  
  33.   struct cmd_element cmdname = \  
  34.   { \  
  35.     cmdstr, \  
  36.     funcname, \  
  37.     helpstr \  
  38.   }; \  
  39.   int funcname \  
  40.   (struct cmd_element *self, struct vty *vty, int argc, char **argv)  


 

SYSCONFIG_NODE和DEVCONFIG_NODE要添加进enum node_type{}中去。

最后就要在init_cmd的最后加进自己的command了

比如

  1. /*add commands to system config node 
  2.   * added by xyang @ 2012-02-01* 
  3.   */  
  4.     /*management network settings*/   
  5.     
  6.     install_element (SYSCONFIG_NODE, &vtysh_system_cfg_ip_cmd);//ip and subnet mask  
  1. /*add commands to system config node 
  2.   * added by xyang @ 2012-02-01* 
  3.   */  
  4.     /*management network settings*/   
  5.     
  6.     install_element (SYSCONFIG_NODE, &vtysh_system_cfg_ip_cmd);//ip and subnet mask  

其中,函数指针需要定义先:

  1. DEFUN (vtysh_system_cfg_ip,  
  2.      vtysh_system_cfg_ip_cmd,  
  3.      "ip ADDRESS NETMASK",  
  4.      "Set system ip address and netmask\n")  
  5. {  
  6.     applyCfg(argv[0],"IPADDR");  
  7.     applyCfg(argv[1],"NETMASK");  
  8.     system(NETWORK_SETTING_SCRIPT);   
  9.     return CMD_SUCCESS;  
  10. }  
  1. DEFUN (vtysh_system_cfg_ip,  
  2.      vtysh_system_cfg_ip_cmd,  
  3.      "ip ADDRESS NETMASK",  
  4.      "Set system ip address and netmask\n")  
  5. {  
  6.     applyCfg(argv[0],"IPADDR");  
  7.     applyCfg(argv[1],"NETMASK");  
  8.     system(NETWORK_SETTING_SCRIPT);   
  9.     return CMD_SUCCESS;  
  10. }  


 

这样,基本上完成了添加node和命令的任务了。

 

其他Zebra-VTYH自带的命令如果不想要的话删除掉就行了。

 

(总完)

阅读(5311) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~