quagga作为一个路由器软件,自然要提供人机接口。

quagga提供snmp管理接口,而且,自然就会有对应的命令行管理格式,当然一般路由软件不会提供界面形式的,也许有webui,然而quagga并没有。

我们要看的就是这个命令行处理的代码 command。

接触过类似命令行的朋友肯定有一点点好奇吧,那么数量庞大的命令和参数输入,还可以提供提示和自动补齐,这肯定不是一件很简单的事情。

下面是一个配置示例:

 !
interface bge0
ip ospf authentication message-digest
ip ospf message-digest-key md5 ABCDEFGHIJK
!
router ospf
network 192.168.0.0/ area 0.0.0.1
area 0.0.0.1 authentication message-digest

哦哦,看到这样的命令,实在是头疼。

嗯,不废话了,我们还是看代码吧,看command是怎么处理这令人头疼的命令行吧:

 void cmd_init(int terminal) {
...... cmdvec = vector_init(VECTOR_MIN_SIZE); /* Install top nodes. */
install_node(&view_node, NULL);
install_node(&enable_node, NULL); /* Each node's basic commands. */
install_element(VIEW_NODE, &show_version_cmd); .....
}

这个就是命令行初始化的简化版本。

quagg使用了非常常见的树形列表来描述所有的命令, cmdvec包含所有的顶层命令节点,节点下面是当前节点的所包含的命令元素.

 struct cmd_node
{
/* Node index. */
enum node_type node; /* Prompt character at vty interface. */
const char *prompt; /* Is this node's configuration goes to vtysh ? */
int vtysh; /* Node's configuration write function */
int (*func) (struct vty *); /* Vector of this node's command list. */
vector cmd_vector;
};

上面已经举过命令行的具体例子,解释和执行命令行的函数如下:

 extern vector cmd_make_strvec (const char *);
extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);

通过查找匹配,找到对应的函数执行:

 /* Execute matched command. */
return (*matched_element->func)(matched_element, vty, argc, argv);

执行的函数由如下的宏声明:

 /* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
struct cmd_element cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
.doc = helpstr, \
.attr = attrs, \
.daemon = dnum, \
}; #define DEFUN_CMD_FUNC_DECL(funcname) \
static int funcname (struct cmd_element *, struct vty *, int, const char *[]); #define DEFUN_CMD_FUNC_TEXT(funcname) \
static int funcname \
(struct cmd_element *self __attribute__ ((unused)), \
struct vty *vty __attribute__ ((unused)), \
int argc __attribute__ ((unused)), \
const char *argv[] __attribute__ ((unused)) ) #define DEFUN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, , ) \
DEFUN_CMD_FUNC_TEXT(funcname)

然后看一个具体命令行声明:

 /* Configration from terminal */
DEFUN(config_terminal,
config_terminal_cmd,
"configure terminal",
"Configuration from vty interface\n"
"Configuration terminal\n") {
if (vty_config_lock(vty)) vty->node = CONFIG_NODE;
else {
vty_out(vty, "VTY configuration is locked by other VTY%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}

这是进入配置模式的命令。

嗯,这个就看到这里吧!

quagga源码分析--通用库command的更多相关文章

  1. quagga源码分析--通用库thread

    quagga是开源路由器软件,提供的用户界面与思科,华为的路由器的人机接口几乎一致,非常有学习价值,尤其是开源的协议代码,简直亮瞎了我的小眼睛. quagga的介绍,我就不赘述了,有兴趣的可以找度娘或 ...

  2. [转]数据库中间件 MyCAT源码分析——跨库两表Join

    1. 概述 2. 主流程 3. ShareJoin 3.1 JoinParser 3.2 ShareJoin.processSQL(...) 3.3 BatchSQLJob 3.4 ShareDBJo ...

  3. quagga源码分析--大内总管zebra

    zebra,中文翻译是斑马,于是我打开了宋冬野的<斑马,斑马>作为BGM来完成这个篇章,嘿嘿,小资一把! zebra姑且戏称它是quagga项目的大内总管. 因为它负责管理其他所有协议进程 ...

  4. quagga源码分析--路由信息处理zebra-rib

    对于各个协议生成的路由信息的处理属于quagga中非常重要的一个功能,如何在内核进行路由增加,更新,删除是一个复杂的过程. quagga在thread任务调度中加入了一种工作队列,work_queue ...

  5. quagga源码分析--内核通信netlink

    Linux操作系统中当CPU处于内核状态时,可以分为有用户上下文的状态和执行硬件.软件中断两种.其中当处于有用户上下文时,由于内核态和用户态的内 存映射机制不同,不可直接将本地变量传给用户态的内存区: ...

  6. quagga源码学习--BGP协议的初始化

    quagga支持BGP-4,BGP-4+协议,支持多协议(mpls,isis,ospf等等)以及单播,组播路由的导入和分发. 具体的协议,这里就不附录了,网络上有很多资料,或者RFC. 协议源码的学习 ...

  7. 从源码分析node-gyp指定node库文件下载地址

    当我们安装node的C/C++原生模块时,涉及到使用node-gyp对C/C++原生模块的编译工作(configure.build).这个过程,需要nodejs的头文件以及静态库参与(后续称库文件)对 ...

  8. 比特币源码分析--C++11和boost库的应用

    比特币源码分析--C++11和boost库的应用     我们先停下探索比特币源码的步伐,来分析一下C++11和boost库在比特币源码中的应用.比特币是一个纯C++编写的项目,用到了C++11和bo ...

  9. Hadoop2源码分析-YARN 的服务库和事件库

    1.概述 在<Hadoop2源码分析-YARN RPC 示例介绍>一文当中,给大家介绍了YARN 的 RPC 机制,以及相关代码的演示,今天我们继续去学习 YARN 的服务库和事件库,分享 ...

随机推荐

  1. 线程池python

    原创博文,转载请注明出处 今天在学习python进程与线程时,无意间发现了线程池threadpool模块,见官方文档. 模块使用非常简单,前提是得需要熟悉线程池的工作原理. 我们知道系统处理任务时,需 ...

  2. 正则表达式(c#)

      只能输入数字:"^[0-9]*$". 只能输入n位的数字:"^\d{n}$". 只能输入至少n位的数字:"^\d{n,}$". 只能输入 ...

  3. Hadoop 使用FileSystem API 读取数据

    代码: package com.hadoop; import java.io.IOException; import java.io.InputStream; import java.net.URI; ...

  4. Varint code

    Varint编码   LevelDB内部通过采用变长编码,对数据进行压缩来减少存储空间,采用CRC进行数据正确性校验.下面就对varint编码进行学习. 传统的integer是以32位来表示的,存储需 ...

  5. SharePoint开发

    做SharePoint开发有时候是一件比较痛苦的事情,毕竟庞大的框架总是笨重的~~ 往往如果采取传统的方式开发SharePoint的话,更改一个代码需要有以下操作: 1)更改代码 2)VS编译——&g ...

  6. Jekyll报'Tag was never closed'错误

    使用jekyll的代码高亮功能.但是发现有时总是很恼人的出现错误,报告说'Tag was never closed'.可是我很确定的关闭了标签啊,真是令人恼怒啊.解决方案式什么哪?如果你对此有兴趣,请 ...

  7. PL/SQL配置大小写转换等快捷键

    Tools(工具) --> Preferences(首选项) --> Key Configuration(键配置) 然后修改自己需要的快捷键方式 作者:itmyhome

  8. picker控件详解与使用,(实现省市的二级联动)

    picker控件详解与使用,(实现省市的二级联动) 第一步:新建一个单视图(single view)的工程, 命名为pickerTest,不要勾选下面两个选项,第一个是新版本里面的,第二个是单元测试, ...

  9. 创建基本的2D场景(part2)

    让我们继续来学习Unity2D游戏场景的制作,本文分为以下3个部分: · 添加角色和控制 . 添加2D物理阻挡 · 添加2D效果 通过制作一个移动帽子接保龄球的小游戏,我们可以学习到任何创建游戏对象, ...

  10. .NET基础——循环、枚举

    1. 循环结构 3种循环语句:while.do-while.for 面对循环我们应当注意: 1. 循环在做什么?(重复做的事情——也就是循环体的内容) 2. 循环的终止条件是什么?(循环条件) 3种循 ...