zoukankan      html  css  js  c++  java
  • zebra代码简单分析

    http://blog.chinaunix.net/uid-21568264-id-203665.html


    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 node都会知道一个函数指针,调用这个函数就会执行相应的命令了
     
     
    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网络编程的掌握了。
    Meet so Meet. C plusplus I-PLUS....
  • 相关阅读:
    Codeforces Round #311 (Div. 2)题解
    firefox 被劫持hao123 主页
    国有航空为啥“放下身段”读春秋?
    ORACLE中常见SET指令
    最大概率法分词及性能測试
    怎样利用JDBC连接并操作Oracle数据库
    hdu5240
    代码调试过程中easy遇到的问题
    最简单的基于FFmpeg的AVDevice样例(读取摄像头)
    FPGA 功耗结构设计
  • 原文地址:https://www.cnblogs.com/iplus/p/4467313.html
Copyright © 2011-2022 走看看