VPP启动

VPP启动在上文说到 在 VPP 启动之前 会提前通过宏定义的方式注册各种需要初始化的业务逻辑函数 本文主要介绍 VPP 的启动流程 nbsp VPP 的入口函数在 src vpp vnet main c1 nbsp nbsp nbsp 加载 startup conf 获取配置信息 VPP 启动 可以通过命令 如 vpp c etc vpp startup conf 启动 startup conf 包含了 VPP 默认的配置信息 涉及多种配置参数

在上文说到,在VPP启动之前,会提前通过宏定义的方式注册各种需要初始化的业务逻辑函数,本文主要介绍VPP的启动流程

 

VPP的入口函数在src/vpp/vnet/main.c

1.   加载startup.conf,获取配置信息

VPP启动,可以通过命令:如vpp –c /etc/vpp/startup.conf启动

startup.conf包含了VPP默认的配置信息,涉及多种配置参数,每个参数用大括号进行区分:

可以包含的默认配置有:具体可见:https://wiki.fd.io/view/VPP/Command-line_Arguments

VPP启动时主要关心:pluginpath和heapsize,获取plugin路径和堆大小

2.   clib_mem_init:

根据默认配置,分配主堆内存

3.   vpe_main_init:

设置VPP提示,

 

注册srp_ips_process_node, srp_input_node, srp_control_input_node3个node节点

 

此处没细研究,主要理解应该是实现旁路操作系统,实现网络数据直接在网卡和VPP之间传递做准备

4.   vlib_unix_main

核心的启动业务逻辑就在该函数中:

int vlib_unix_main (int argc, char *argv[])

{

 vlib_main_t *vm = &vlib_global_main;        /*one and only time for this! */

 vlib_thread_main_t *tm = &vlib_thread_main;

 unformat_input_t input;

  u8*thread_stacks;

 clib_error_t *e;

  inti;

 

 vm->argv = (u8 ) argv;

 vm->name = argv[0];

 vm->heap_base = clib_mem_get_heap ();

 ASSERT (vm->heap_base);

 

 unformat_init_command_line (&input, (char ) vm->argv);

  //获取plugin信息并填充结构体

if ((e = vlib_plugin_config (vm, &input)))

    {

     clib_error_report (e);

     return 1;

    }

 unformat_free (&input);

 

  //加载启动插件功能

  i =vlib_plugin_early_init (vm);

  if(i)

   return i;

 

 unformat_init_command_line (&input, (char ) vm->argv);

  if(vm->init_functions_called == 0)

   vm->init_functions_called = hash_create (0, /* value bytes */ 0);

  //启动所有宏定义VLIB_EARLY_CONFIG_FUNCTION和VLIB_CONFIG_FUNCTION注册的链表函数

e = vlib_call_all_config_functions (vm, &input, 1 /* early */ );

  if(e != 0)

    {

     clib_error_report (e);

     return 1;

    }

 unformat_free (&input);

 

  /*

   *allocate n x VLIB_THREAD_STACK_SIZE stacks, aligned to a

   *VLIB_THREAD_STACK_SIZE boundary

   *See also: os_get_cpu_number() in vlib/vlib/threads.c

   */

 thread_stacks = clib_mem_alloc_aligned

   ((uword) tm->n_thread_stacks * VLIB_THREAD_STACK_SIZE,

    VLIB_THREAD_STACK_SIZE);

 

 vec_validate (vlib_thread_stacks, tm->n_thread_stacks – 1);

  for(i = 0; i < vec_len (vlib_thread_stacks); i++)

    {

     vlib_thread_stacks[i] = thread_stacks;

 

     /*

      * Disallow writes to the bottom page of the stack, to

      * catch stack overflows.

      */

     if (mprotect (thread_stacks, clib_mem_get_page_size (), PROT_READ) <0)

         clib_unix_warning(“thread stack”);

 

     thread_stacks += VLIB_THREAD_STACK_SIZE;

    }

 

 //这里启动thread0

  i =clib_calljmp (thread0, (uword) vm,

                       (void *) (vlib_thread_stacks[0] +

                                  VLIB_THREAD_STACK_SIZE));

 return i;

}

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

调用vlib/中的vlib_main函数

vlib_main (vlib_main_t * volatile vm,unformat_input_t * input)

{

 clib_error_t *volatile error;

 

 vm->queue_signal_callback = dummy_queue_signal_callback;

 

 clib_time_init (&vm->clib_time);

 

  /*Turn on event log. */

  if(!vm->elog_main.event_ring_size)

   vm->elog_main.event_ring_size = 128 << 10;

 elog_init (&vm->elog_main, vm->elog_main.event_ring_size);

 elog_enable_disable (&vm->elog_main, 1);

 

  /*Default name. */

  if(!vm->name)

   vm->name = “VLIB”;

 

 vec_validate (vm->buffer_main, 0);

 vlib_buffer_cb_init (vm);

 

  if((error = vlib_thread_init (vm)))

    {

     clib_error_report (error);

     goto done;

    }

 

 //启动宏定义VLIB_REGISTER_NODE注册的所有node节点功能函数,功能比较简单,就是将各个节点加到一个vlib_node_main_t-> nodes

  /*Register static nodes so that init functions may use them. */

 vlib_register_all_static_nodes (vm);

 

  /*Set seed for random number generator.

    Allow user to specify seed to make random sequence deterministic. */

  if(!unformat (input, “seed %wd”, &vm->random_seed))

   vm->random_seed = clib_cpu_time_now ();

 clib_random_buffer_init (&vm->random_buffer, vm->random_seed);

 

  /*Initialize node graph. */

//初始化node graph,看代码基本就是填充节点关系字段

  if((error = vlib_node_main_init (vm)))

    {

     /* Arrange for graph hook up error to not be fatal when debugging. */

     if (CLIB_DEBUG > 0)

         clib_error_report(error);

     else

         gotodone;

    }

 

  /*See unix/main.c; most likely already set up */

  if(vm->init_functions_called == 0)

   vm->init_functions_called = hash_create (0, /* value bytes */ 0);

//启动所有宏定义VLIB_INIT_FUNCTION:注册的链表函数

if ((error = vlib_call_all_init_functions(vm)))

   goto done;

 

  /*Create default buffer free list. */

 vlib_buffer_get_or_create_free_list (vm,

                                            VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES,

                                            “default”);

 

 switch (clib_setjmp (&vm->main_loop_exit,VLIB_MAIN_LOOP_EXIT_NONE))

    {

   case VLIB_MAIN_LOOP_EXIT_NONE:

     vm->main_loop_exit_set = 1;

     break;

 

   case VLIB_MAIN_LOOP_EXIT_CLI:

     goto done;

 

   default:

     error = vm->main_loop_error;

     goto done;

    }

 

  if((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))

   goto done;

 

 

  /*Call all main loop enter functions. */

  {

   clib_error_t *sub_error;

   //启动宏定义VLIB_MAIN_LOOP_ENTER_FUNCTION指定的函数,这里主要启动thread.c中的start_workers

 sub_error =vlib_call_all_main_loop_enter_functions (vm);

   if (sub_error)

     clib_error_report (sub_error);

  }

  //处理节点的核心功能函数

 vlib_main_loop (vm);

 

done:

  /*Call all exit functions. */

  {

   clib_error_t *sub_error;

   sub_error = vlib_call_all_main_loop_exit_functions (vm);

   if (sub_error)

     clib_error_report (sub_error);

  }

 

  if(error)

   clib_error_report (error);

 

 return 0;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232238.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 怎样用Google APIs和Google的应用系统进行集成(1)—-Google APIs简介

    怎样用Google APIs和Google的应用系统进行集成(1)—-Google APIs简介

    2022年1月20日
    50
  • Tess4j maven demo[通俗易懂]

    Tess4j maven demo[通俗易懂]tess4j实现文字识别Demo,下面为内容实现源码,内容仅为一个demo,demo下载地址:tess4jDemopublicclassTess4JTest{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(newLoggHelper().toString());staticfinaldo…

    2022年6月14日
    30
  • 在vue3 中使用echarts

    在vue3 中使用echarts1,安装echartsnpminstallecharts–save有cnpm的可以cnpm安装2,在main.js中导入import{createApp}from’vue’importAppfrom’./App.vue’import*asechartsfrom’echarts’constapp=createApp(App).mount(‘#app’)app.echarts=echarts3,在需要使用的页面,定义div&lt

    2025年7月25日
    3
  • 递归

    递归递归

    2022年4月24日
    34
  • 《架构之美》笔记_印象笔记如何创建目录

    《架构之美》笔记_印象笔记如何创建目录美是创造矛盾并解决矛盾。架构的多关注点(例如业务逻辑、系统扩展性、持久、并发)和简洁性就是一种矛盾,美丽的架构能解决这种矛盾,使人内心产生愉悦;随着关注点的增加,架构也在不断演进;术:分层、组件化、服务化、标准化、缓存、分离、队列、复制、冗余、代理;道:如何恰到好处地使用术,例如顿悟变化的道理、博弈中寻找平衡、相对与绝对的奥秘、开放的心态;爱因斯坦说:『让它尽可能简单,但不要过于简单』,美

    2025年6月10日
    4
  • pandorabox软件包安装_路由器pandora无法移除插件

    pandorabox软件包安装_路由器pandora无法移除插件下载或直接通过opkg在线安装luci-app-xunlei,链接:http://pan.baidu.com/s/1qYB4gDe密码:13tq不要安装到U盘,否则页面上不会显示“迅雷远程下载”项安装完后进行配置使能xunlei启动项然后把云盘里的Xware1.0.30_mipsel_32_uclibc.zip解压到挂载点/mnt/sdxx/xunle

    2025年6月10日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号