ovs源码剖析

ovs controller和manager

2020-12-27  本文已影响0人  分享放大价值

controller 是针对网桥设置的,ovs-ofctl可以通过controller连接到网桥执行命令。
manager只针对ovsdb-server,一个host上只会有一个manager,ovs-vsctl/ovsdb-client可以通过manager连接到ovsdb-server。

controller

ovs支持两种类型的 openflow controllers

Primary controllers
    This is the kind of controller envisioned by the OpenFlow 1.0 specification. Usually, a
    primary controller implements a network policy by taking charge of the switch’s flow table.
    Open vSwitch initiates and maintains persistent connections to primary controllers, retrying the connection each time it fails or drops. The fail_mode column in the Bridge table
    applies to primary controllers.
    Open vSwitch permits a bridge to have any number of primary controllers. When multiple controllers are configured, Open vSwitch connects to all of them simultaneously.
    Because OpenFlow 1.0 does not specify how multiple controllers coordinate in interacting with a single switch, more than one primary controller should be specified only if the
    controllers are themselves designed to coordinate with each other. (The Nicira-defined
    NXT_ROLE OpenFlow vendor extension may be useful for this.)
Service controllers
    These kinds of OpenFlow controller connections are intended for occasional support and
    maintenance use, e.g. with ovs−ofctl. Usually a service controller connects only briefly
    to inspect or modify some of a switch’s state.
    Open vSwitch listens for incoming connections from service controllers. The service
    controllers initiate and, if necessary, maintain the connections from their end. The
    fail_mode column in the Bridge table does not apply to service controllers.
    Open vSwitch supports configuring any number of service controllers

可以通过设置controller时target的格式来确定是哪种controller,
ovs-vsctl set-controller br1 target

如果target为如下两种,则为primary controllers,ovs会主动连接controller
  ssl:ip[:port]
  tcp:ip[:port]
        
如果target为如下几种,则为service controller,ovs会监听设置的端口或者路径,等待客户端连接
  pssl:[port][:ip]
  ptcp:[port][:ip]
  punix:/usr/local/var/run/openvswitch/br1.*

ovs提供的给bridge添加controller的命令ovs-vsctl set-controller br1 target,实际会在ovs的如下两个表中添加内容,首先会在controller表中添加controller的信息,然后bridge的controller列指向添加的controller(设置为controller的UUID)。

Controller TABLE
    每行表示一个controller。
    Open vSwitch supports two kinds of OpenFlow controllers: Primary controllers 和 Service controllers
    通过 target 来区分是哪种controller。

Bridge TABLE
    controller: set of Controllers

此命令行对应的代码如下

cmd_set_controller
    struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
    struct ovsrec_controller **controllers;
    struct ovsrec_bridge *br;
    size_t n;

    vsctl_context_populate_cache(ctx);

    br = find_real_bridge(vsctl_ctx, ctx->argv[1], true)->br_cfg;
    verify_controllers(br);

    //删除之前设置的controller
    delete_controllers(br->controller, br->n_controller);

    n = ctx->argc - 2;
    //在controller table中添加设置的controller
    controllers = insert_controllers(ctx, &ctx->argv[2], n);
        struct ovsrec_controller **controllers;
        size_t i;
        const char *inactivity_probe = shash_find_data(&ctx->options,
                                                       "--inactivity-probe");

        controllers = xmalloc(n * sizeof *controllers);
        for (i = 0; i < n; i++) {
            if (vconn_verify_name(targets[i]) && pvconn_verify_name(targets[i])) {
                VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
            }
            controllers[i] = ovsrec_controller_insert(ctx->txn);
            ovsrec_controller_set_target(controllers[i], targets[i]);
            if (inactivity_probe) {
                int64_t msecs = atoll(inactivity_probe);
                ovsrec_controller_set_inactivity_probe(controllers[i], &msecs, 1);
            }
        }

        return controllers;
        
    //设置controller到bridge的controller列
    ovsrec_bridge_set_controller(br, controllers, n);
    free(controllers);

由上面代码可知,每次添加controller时都会把bridge上之前配置的controller先删除,再添加新的controller信息。而且可以同时添加多个controller,如下给br1设置三个controller

ovs-vsctl  set-controller br1 ptcp:5555:192.168.122.20 ptcp:5556:192.168.122.20 ptcp:5557:192.168.122.20

各自场景
Primary controllers
openstack场景下,neutron会作为controller,ovs主动连接到neutron上。

    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "vhu2d838c46-a1"
            tag: 56
            Interface "vhu2d838c46-a1"
                type: dpdkvhostuserclient
                options: {vhost-server-path="/run/openvswitch/vhu2d838c46-a1"}

Service controllers
每创建一个网桥,ovs-vswitchd会默认创建 /usr/local/var/run/openvswitch/br1.mgmt 文件并且监听,ovs-ofctl命令执行命令时,会默认连接到此文件。

通过给 bridge 添加 service controller,就可以使用其他方式或者路径执行命令,而不用再使用默认的unix 文件。有如下三种方式,
pssl:port:ip
ptcp:port:ip
punix:path -- path只能和默认的 br1.mgmt 在同一个目录

下面实践Service controllers的后两种方式: ptcp和punix

a. 给 bridge 添加 Service controller ptcp:5555:192.168.122.20 后,会监听此端口号
root@master:~# ovs-vsctl  set-controller br1 ptcp:5555:192.168.122.20
root@master:~# ovs-vsctl show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "ptcp:6640:192.168.122.20"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

#ovs-ofctl 连接新controller
root@master:~# ovs-ofctl show tcp:192.168.122.20:5555
OFPT_FEATURES_REPLY (xid=0x2): dpid:000056138db6204c
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 LOCAL(br1): addr:56:13:8d:b6:20:4c
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

b. 设置 bridge 的 service controller 为 punix:/usr/local/var/run/openvswitch/br1.test
root@master:~# ovs-vsctl  set-controller br1 punix:/usr/local/var/run/openvswitch/br1.test
root@master:~# ovs-vsctl show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "ptcp:6640:192.168.122.20"
    Bridge "br1"
        Controller "punix:/usr/local/var/run/openvswitch/br1.test"
        Port "br1"
            Interface "br1"
                type: internal

#ovs-ofctl 连接新controller
root@master:~# ovs-ofctl show unix:/usr/local/var/run/openvswitch/br1.test
OFPT_FEATURES_REPLY (xid=0x2): dpid:000056138db6204c
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 LOCAL(br1): addr:56:13:8d:b6:20:4c
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0


#删除指定 bridge 的 controller
ovs-vsctl  del-controller br4

manager

默认情况下,可以在host上使用 "unix:/usr/local/var/run/openvswitch/db.sock" 连接到ovsdb-server,manager用于配置和ovsdb-server通信方式,配置manager后,就可以通过新的manager连接 ovsdb-server,只能添加一个manager。
manager格式有如下6种,如果非unix/punix的方式,还可以在其他能通信的host上连接ovsdb-server。

//配置成这三种,表示ovsdb-server为active类型,会主动发起连接
  tcp:ip:port
  unix:path
  ssl:ip:port
//配置成这三种,表示ovsdb-server为passive类型,会监听端口或者path,等待客户端连接
  ptcp:port:ip
  punix:path
  pssl:ip:port

下面验证 tcp 和 unix 的方式,ssl的暂时不考虑

a. 配置 manager 为 ptcp:6640:192.168.122.20,此时host上监听 6640 端口号,等待客户端连接(比如ovs-vsctl,ovsdb-client)
root@ubuntu:~#ovs-vsctl set-manager ptcp:6640:192.168.122.20
root@master:~#ovs-vsctl show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "ptcp:6640:192.168.122.20"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

#通过新的manager连接ovsdb-server,因为连接为tcp类型,所以在可任何能和ovsdb-server主机通信的设备上
#连接ovsdb-server,执行 show 命令
root@ubuntu:~#ovs-vsctl --db=tcp:192.168.122.20:6640 show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "ptcp:6640:192.168.122.20"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal
                
b. 配置 manager 为 punix:/root/a
root@master:~#ovs-vsctl set-manager punix:/root/a
root@master:~# ovs-vsctl --db=unix:/root/a show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "punix:/root/a"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

#通过新的manager连接ovsdb-server
root@master:~#ovs-vsctl --db=unix:/root/a
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "punix:/root/a"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

c. 配置 manager 为 tcp:192.168.122.20:6640,此时ovsdb-server会不断尝试连接到 192.168.122.20:6640
root@master:~# ovs-vsctl set-manager tcp:192.168.122.20:6640
#此时执行ovs-vsctl命令时,将 --db 写成 ptcp:6640:192.168.122.20,就会启动监听端口,ovsdb-server会连接上去,继而执行show命令
root@master:~# ovs-vsctl --db=ptcp:6640:192.168.122.20 show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "tcp:192.168.122.20:6640"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

d. 配置 manager 为 unix:/root/a
root@master:~#ovs-vsctl set-manager unix:/root/a
#此时执行ovs-vsctl命令时,将 --db 写成 punix:/root/a,ovsdb-server会连接上去,继而执行show命令
root@master:~# ovs-vsctl --db=punix:/root/a show
eeba339a-af9a-41b4-abd5-6ea7645196b7
    Manager "unix:/root/a"
    Bridge "br1"
        Controller "ptcp:5555:192.168.122.20"
        Port "br1"
            Interface "br1"
                type: internal

连接方式

在ovs的命令行中,经常能看到如下两种格式,下面简单介绍下
tcp:ip:port -- 此种方式表示主动连接指定的ip和port。
ptcp:port:ip -- 此种方式表示被动连接(passive),会在本地创建监听端口port,等待客户端连接。
注意ptcp格式时port在ip的前面,而tcp格式时port在ip的后面,如果格式指定错了,就不能正常的工作。

参考

controller和manager都属于db的table,可以参考如下官网文档,了解它们的区别和用途
http://www.openvswitch.org//ovs-vswitchd.conf.db.5.pdf

上一篇下一篇

猜你喜欢

热点阅读