您的位置:首页 > 其它

quagga 各部分通讯备忘

2015-06-09 11:11 288 查看
vtysh:与其它守护进程通过socket交互

struct vtysh_client

{

    int fd;

    const char *name;

    int flag;

    const char *path;

} vtysh_client[]

结构保存守护进程信息

vtysh_init_vty

vtysh: 提供shell

   //命令行接口

   main{vtysh_execute (line_read);}

   ->vtysh_execute

   ->vtysh_execute_func

   ->vtysh_client_execute(write (vclient->fd)

  

zebra deamon: 主要负责底层借口

   //命令行接口

   main

   ->vty_serv_sock(ZEBRA_VTYSH_PATH)

   ->vty_serv_un

   ->vty_event

  

   //底层借口

   main

   ->kernel_init

   ->kernel_read

   //其他协议接口 UNIX PATH

   ZEBRA_SERV_PATH

  

   ->zebra_zserv_socket_init

   ->zebra_serv_un

   ->zebra_event(ZEBRA_SERV)

   ->zebra_accept              loop to  zebra_event(ZEBRA_SERV)

   ->zebra_client_create

   ->zebra_event(ZEBRA_READ)  

   ->zebra_client_read()       loop to  zebra_event(ZEBRA_READ)

rip: //rip 协议

   //命令行接口

   main()

   ->vty_serv_sock() (同时制作网络接口与UNIX与接口, unix for vtysh /AF_INET for telnet)

   ->vty_serv_un

   ->vty_event(VTYSH_SERV)

   ->vtysh_accept

   ->vty_event(VTYSH_READ)

   ->vty_execute

   ->vty_command

   ->cmd_execute_command_real

   //协议接口

   main

   ->thread_fetch->thread_call

   回调

   RIP 经过初始化后,然后进入一个 while 死循环,在这个死循环中根据不同的优先级去执行不同的线程钩子函数。钩子注册 void  rip_event (enum rip_event event, int sock) 函数。

“router rip”对应command list中的“router_rip”函数,代码如下定义的

DEFUN (router_rip,

       router_rip_cmd,

       "router rip",

       "Enable a routing process\n"

       "Routing Information Protocol (RIP)\n")

创建了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);

 

   更新协议

   //zebra

   ->main

   ->rip_zclient_init

   ->zclient_init()

   ->zclient_event(ZCLIENT_SCHEDULE)

   ->zclient_connect

   ->zclient_start

  

  

/******************************************

   使用简介

*******************************************/

  

基于ospf的配置

#cd /etc/zebra

#touch ospfd.conf

#/etc/rc.d/init.d/zebra start                 启动zebra这个服务

#/etc/rc.d/init.d/ospfd start                 启动ospfd

好了,目前能登陆路由

#vtysh

如果按”?”键列出的内容,能查看相关命令。

键入"enable" 进入终极模式,此时提示符的 ">" 会变成 "#"

#configure terminal  目前进入设置模式

提示会变成类似  localhost(config)#  ,就表示进入了设置模式了。

输入命令:interface eth0

提示会变成类似  localhost(config-if)#

目前就能设置第一张网卡了,

localhost(config-if)# ip address 192.168.1.166/24

(默认此网卡是死的,需要手动激活才能使用)

localhost(config-if)# no shutdown    #这就是激活了。

localhost(config-if)# exit           #推出eth0的设置

设置第二张网卡

localhost(config)# interface eth1

localhost(config-if)# ipadress 192.168.4.4/24

localhost(config-if)# no shutdown

localhost(config-if)# exit

接着就是设置协议

localhost(config)# router ospf

显示“localhost(config-router)# ” 接着输入命令

localhost(config-router)# network 192.168.1.0/24 area 1

localhost(config-router)# network 192.168.4.0/24 area 1

以上是指定区域为 “1”区

localhost(config-router)# end

结束设置

然后复制一个文件

localhost#  copy running-config startup-config

查看路由的信息能使用:show running-config

显示路由器学习路由知识情况用:show ip route

好了,这样就完成1和4 网段之间的动态路由了,如有更多网段,则在设置网卡的步骤中多

添加几个相似的设置就能了。

下面是基于rip的设置:

几乎所有步骤都相同

#cd /etc/zebra

#touch ripd.conf

#/etc/rc.d/init.d/zebra start                 启动zebra这个服务

#/etc/rc.d/init.d/ripd start                  启动ospfd

好了,目前能登陆路由

#vtysh

输入命令:interface eth0

目前设置第一张网卡

localhost(config-if)# ip address 192.168.1.166/24

localhost(config-if)# no shutdown  

localhost(config-if)# exit          

设置第二张网卡

localhost(config)# interface eth1

localhost(config-if)# ipadress 192.168.4.4/24

localhost(config-if)# no shutdown

localhost(config-if)# exit

设置协议

localhost(config)# router rip

localhost(config-router)# network 192.168.1.0/24

localhost(config-router)# network 192.168.4.0/24

localhost(config-router)# version 2

localhost(config-router)# end

结束设置

然后复制一个文件

localhost#  copy running-config startup-config

查看路由的信息能使用:show running-config

显示路由器学习路由知识情况用:show ip route

////////////////////////////////

以下转载:
http://blog.chinaunix.net/space.php?uid=21568264&do=blog&id=203665 zebra代码简单分析(2011-04-02 11:35)
标签:

zebra 源代码 分类:
porting
web site: http://www.zebra.org/
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 no
4000
de都会知道一个函数指针,调用这个函数就会执行相应的命令了

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网络编程的掌握了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: