OVS源码--ovs-vswitchd(二)

一、主要函数

vswitchd 作为守护进程和ovsdb 通信以及和controller 进行openflow 通信,并完成和底层内核的交互。
在这里插入图片描述

  • set_program_name(argv)

    设置程序名称、版本、编译日期等信息

  • proctitle_int(argh,argv)

    复制出输入的参数列表到新的存储中,让argv指向这块内存【主要是为了后面的proctitle_set()函数准备】

  • service_start(&argc,&argv)
    注册回调和服务管理器出现故障错误时操作的配置

  • remote=parse_options(argh,argv,&unixctl_path)

    解析参数,其中unixctl_path存储unixctrl域的sock名,作为接受外部控制命令的渠道;而remote存储连接到ovsdb的信息,即连接到配置数据库的sock名

  • ovsrec_init()

    数据表结构初始化,包括13张数据表

  • daemonize_start()

    如果系统守护进程被配置了,启动系统守护进程,通过派生和在返回的子进程。父进程徘徊,直到让子进程知道它完成启动成功(通过调daemon_complete()),或者它没有启动(用非零退出退出代码。

  • unixctl_server_create(unixctl_path,&unixctl)

    创建一个unixctl_server(存放在unixctl),并监听在unixctl_path指定的punix路径,该路径作为ovs-appctl发送命令给ovsd的通道

  • unixctl_command_register

    注册unixctl命令

  • bridge_init

    从remote数据库获取配置信息,并初始化bridge

1、主循环

  • memory_run()

    运行内存监视器,客户端调用memory_should_report()。此函数以及该模块的接口的剩余部分,仅被一个线程调用。

  • bridge_run

    主要对网包进行完整处理过程。包括完成必要的配置更新【在配置更新中会从数据库中读取配置信息,生成必要的bridge和dp等数据结构】

    • ovsdb_idl_run(idl);

      处理了一批从’IDL’数据库服务器的消息。这可能会导致IDL的内容发生变化。客户端可以检查与ovsdb_idl_get_seqno()。

    • system_stats_enable(false);

      因为我们不运行system_stats的run()在这个进程中有多个OVS-vswitchd守护进程的现状,关闭系统自动统计信息收集。

    • bridge_init_ofproto(cfg)

      初始化ofproto库。这仅需要执行一次,但配置设置之后它必须要做的。如果已经出现了初始化,bridge_init_ofproto()立即返回。

    • bridge_run__(void)

      • ofproto_run中的p->ofproto_class->run( p) 上的run函数依次调用函数

        • 必选调用dpif_run()处理所有注册的netlink notifier的汇报事件
        • 必选调用run_fast()处理常见的周期事件,包括对upcalls的处理等
        • 可选调用netflow_run()和sflow_run(),进行对netflow和sflow的支持
        • 可选调用较多,自行查看
      • connmr_run函数处理与控制器的周期性交互

        • 首先检查是否存在in_band的控制器
        • 调用ofconn_run()处理对ofproto的协议解析和行动
        • rconn_run(ofconn->rconn)负责连接到controller
        • rconn_recv(ofconn->rconn)负责从controller收取消息
        • handle_openflow()最终调用handle_openflow__()(ofproto/ofproto.c)来完成对各个Of消息的处理

    以 PACKET_OUT消息为例,调用的是handle_packout 函数

    首先调用ofputil_decode_packet_out()对of消息进行解析
    调用ofconn_pktbuf_retrieve()获取payload信息
    利用ofproto_class->packet_out()将网包发出
    
    packet_out()
    {   
        ofproto_dpif_execute_actions()
            {
            dpif_flow_stats_extract() 流状态提取
            xlate_actions()将ofpacts转化为dp的行动格式odp_actions
            调用dpif_execute()函数让dpif执行给定的action构建OVS_PACKET_CMD_EXECUTE netlink消息并发给datapath
            datapath中将对应调用ovs_packet_cmd_execute函数处理收到的nlmsg
            ovs_packet_cmd_execute的调用过程
            ovs_packet_cmd_execute()->ovs_execute_actions()->do_execute_actions()
            }
    }
    
    • 重新配置SSL

      通过主循环每一次遍历,而不是只当数据库的变化,因为密钥和证书文件的内容可以更改在数据库不更改中。我们完成这些在bridge_reconfigure()之前,因为该功能可能会启动SSL连接之前做到这一点,因此需要SSL进行配置。

    • 对all_bidge上的每个bridge的ofproto执行ofproto_run()

  • netdev_run()

    如果打开了一些netted,则执行对应在netdev_classes上定义的每个netdev_class实体,调用它们的run()包括处理网卡注册的各个通知事件,获取网卡的最新的信息等

  • unixctl_server_run(unixctl)

    从unixctl指定的server中获取来自ovs-appctl发出的命令数据,并执行对应的命令

  • 循环等待事件处理

    包括memory、bridge、unixctl_server、netted等事件,被poll_fd_wait()注册的最短时间

  • poll_block(void)

    阻塞知道之前被poll_fd_wait()注册过的事件发生,或者等待时间超过poll_timer_wait()注册的最短时间

  • 清理工作

    退出bridge,关闭unixctl连接

二、处理流程

代码在vswitchd/目录下面,可以从main 函数入口分析,整体处理流程如下:
在这里插入图片描述

原文链接:https://www.sdnlab.com/my_sdnlab/wp-content/uploads/2017/02/cntctfrm_1a5b490b5708a374ad0d207df48ec29e_Openvswitch%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章