zoukankan      html  css  js  c++  java
  • Cisco VPP启动流程

    Cisco VPP启动流程,有需要的朋友可以参考一下。

    VPP初始化

    VLIB_INIT_FUNCTION用来定义构造函数,注册函数到vlib_main_t->init_function_registrations,这个链表在main()函数之前创建。

    vlib_main()->vlib_call_all_init_functions()注册的函数在这里被调用初始化,最后执行函数vlib_main_loop()。

    像这样由宏定义和构造函数创建的全局链表的方式还有如下几个:

    ·VLIB_API_INIT_FUNCTION

    ·VLIB_CLI_COMMAND

    ·VLIB_CONFIG_FUNCTION

    ·VLIB_EARLY_CONFIG_FUNCTION

    ·VLIB_MAIN_LOOP_ENTER_FUNCTION

    ·VLIB_MAIN_LOOP_EXIT_FUNCTION

    ·VLIB_REGISTER_NODE

    vpp/vnet/main.c的main()函数

    程序的入口,设置vlib_plugin_main.handoff_structure_get_cb函数指针,指向vpp/vnet/main.c中的函数vnet_get_handoff_structure。

    vlib/unix/plugin.c中的vnet_get_handoff_structure()函数调用上面的的函数指针handoff_structure_get_cb。

    vnet_get_handoff_structure() 定义了一个静态变量,这个静态变量包含了主要数据指针,比如vlib_main,vnet_main和ethernet_main(看代码没有vlib_main)。每个插件注册的时候,都会通过vlib_plugin_register()将以上数据传递给插件。

    最后调用vlib_unix_main()。

    vlib/unix/main.c的vlib_unix_main()函数

    vlib_plugin_early_init()函数会通过dlopen加载插件目录下的所有插件,这个目录可以通过命令行指定。默认的插件路径是/usr/lib/vpp_plugins。

    dlopen每个插件后,VPP会获取函数vlib_plugin_register的符号地址,所以每个插件都要求实现该函数,之前说过这个函数会传递非常重要的数据。

    vlib_call_all_config_functions()函数解析所有的命令行选项,并且针对前期需求配置。

    为以下线程创建线程栈,主要有三种类型的线程需要实现:

    普通线程:比如统计采集。

    EAL线程:处理包的工作。

    Processes:这些都是定期执行、相互协作的多线程。比如DHCP租期续订的线程等。VPP主线程的超时到期之后会执行这些。

    最后,该函数跳转到thread0()函数。

    vlib/unix/main.c的thread0()函数

    调用vlib/main.c的vlib_main()函数

    vlib/main.c的vlib_main()函数

    VLIB_REGISTER_NODE定义图节点,注册到vlib_main_t->node_registrations,vlib_register_all_static_nodes()遍历这个链表,创建图结点(不是连接,是创建)。

    VLIB_INIT_FUNCTION声明的函数,由vlib_call_all_init_functions()调用初始化。

    如果结点被创建,vlib/node.c的vlib_node_main_init()会对图结点进行初始化。

    VLIB_MAIN_LOOP_ENTER_FUNCTION注册一个链表,vlib_call_all_main_loop_enter_functions()函数遍历该链表。

    调用vlib_main_loop()

    vlib/main.c的vlib_main_loop()函数

    创建前面提到的相互协作的多线程,在while(1)循环中处理不同类型的图结点。

    ·VLIB_NODE_TYPE_PRE_INPUT:类似DBG_CLI的结点

    ·VLIB_NODE_TYPE_INPUT:这些是主要结点,主要从网卡或者硬件加速器获取数据包

    ·进程等待信号,这个很重要,因为所有的客户端都要通过共享内存和VPP通信。客户端向共享内存发送一些API消息,并且向VPP发送信号(SIGUSR1)。

    输入结点组织数据包,并且将他们发送到合适的中间结点。由dispatch_pending_node()进一步处理这些数据包。

  • 相关阅读:
    Python之图片格式转换
    pip依赖安装与记录
    Spectral Graph Theory的一些定理
    Beamer加中文
    Python之json
    Windows之建立C++开发环境
    Mysql分表教程
    null和空 not null
    yii 隐藏index.php的步骤
    yii泛域名
  • 原文地址:https://www.cnblogs.com/kb342/p/6474756.html
Copyright © 2011-2022 走看看