zebra命令存储原理和使用方法

zebra在设计命令格式时,将命令节点NODE和命令COMMAND分开,整个命令结构是一个树状,如图


NODEn表示命令节点,CMDn表示具体命令,在zebra的整个命令行设计当中,zebra用向量的概念将命令和节点连接起来,一个全局向量CMDVEC,指向整个命令结构,CMDVEC的每个索引值都是一个具体的命令节点,在每个命令节点的结构中又存在各自的命令向量cmdvector,该向量指向隶属于该节点的命令,cmd_vector终端额每个索引值都是一个具体的命令。程序索引顺序为CMDVEC->NODEn->CMD1。

命令的注册过程

zebra要成功注册一个命令,需要以下几个步骤:

(1)安装一个新节点(如无需安装可省略这步)

(2)写一条命令的实现

(3)将一条命令挂到节点下

 

/* struct for vector */
struct vector 
{
  unsigned int max;                         /* max number of used slot */

  unsigned int alloced;                     /* number of allocated slot */

  void **index;                             /* index to data */
};

 


在zebra.h中定义,表示一个向量结构,在该结构中,max表示目前使用的最大slot,alloced 表示被分配到的slot,max<=alloced,index通过索引方式。存储value.

命令节点

struct cmd_node
{
      /*node inedx*/
     enum node_type node;
     char *prompt;
     int vtysh;  /*is this node's configuration goes to vtysh?*/
      int (*func)(struct vty *);
     vector cmd_vecotr;
      
};
该结构在command.h中定义,用来表示一个命令节点,节点的类型由node_type枚举指出,节点的标识字符由prompt表示,func表示该节点对应的操作方法。该节点下的命令由vector定义的cmd_voctor表示,例如,在全局配置模式下,命令节点的定义可以是:


 

struct cmd_node config_node=
{
 CONFIG_NODE,
"%s(config)#",
1
};


此外,command.h中还定义了一个重要的结构,就是cmd_element结构,该结构定义了一条命令的全部信息,定义如下

struct cmd_element
{
	char *string;     //command specification by string
	int (*func)(struct cmd_element*,struct vty *,int ,char **);
	char *doc;       //documentation of this command;
	int daemon;  
	vector strvec;   //pointing out each description vector
	int cmdsize;      //command index count;
	char *config;		//configuration string
	vector subconfig;  
}

string描述了命令的实现串,比如我们要显示摸个配置信息“show where you are 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中定义:

 

struct cmd_node menger_node=
{
	MENGER_NODE,
	"%s(menger)# ",
	1
};


 

MENGER_NODE添加到node_type中,然后用install_node将这个节点安装到cmdvec中,install_node(&menger_node,NULL);
 
    
    
写一条命令的实现方法
    
    
zebtas实现命令的方法由command.h中的一个宏来实现
/*DEFUN for vty command interface*/
#define DEFUN(funcname,cmdname,cmdstr,helpstr)\
	int funcname(struct cmd_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.c文件,照着样子写一条命令实现方法。
 
    
    
例如我实现的一个简单方法: 
DEFUN(menger_hello,
		menger_hello_cmd,
		"menger say hello",
		"greet\n"
		"greet to someone\n")
{
	vty_out(vty,"hello,you can do like this %s",VTY_NEWLINE);
	return CMD_SUCCESS;
}	


 

但是这样子还不够,要进入menger_node节点还得靠一个触发命令

 

DEGUN(menger_enable,
	     menger_enable_cmd,
	      "menger",
	      "turn on privileged mode command\n")
{
	vty->node=MENGER_NODE;
	return CMD_SUCESS;
}	

 

安装命令

命令安装的实质是将一个cmd_element结构存储到cmd_node结构中的成员cmd_vec向量的一个未被使用的slot里。

调用接口:void install_element(enum node_type, struct cmd_element *cmd);

将刚才写好的命令安装到定义的节点下,在command.c中添加;

/*为了进入自定义节点,需要安装触发节点*/

install_element(ENABLE_NODE,&menger_enable_cmd);

install_element(MENGER_NODE,&menger_hello_cmd);

 

【本博客 http://www.cnblogs.com/iTsihang 中原创之博文,版权属作者所有,欢迎转载。转载之时请保留本段内容,否则作者将保留追究版权之权利】


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值