一、Bridge 和 ofproto 的区别
一般而言,我们所说的网桥 Bridge 和交换机 Switch 指的都是同一个东西,它是一个工作在数据链路层的网络设备,具有多个端口,通过将数据包从一个端口接收再从其他端口发送出去来实现不同网段之间的通信功能(当然也有很多文章详细阐述了二者具体的区别,但很少有人会刻意区分它们)。在 Open vSwitch 中这二者也是同一个东西,只不过分别用两个数据结构来描述,即 bridge 和 ofproto,分别在 网桥 Bridge 相关的结构 和 ofproto 相关结构体 中有过介绍。
(1)bridge
如下图所示,这是一个交换机。
对于 Open vSwitch 的 bridge 结构体而言,它描述的是上面这样的一个交换机:用户不需要关心交换机内部的转发功能是如何实现的,只需要使用相应的端口,然后当作一个可以按照规则转发数据的“黑盒子”即可。bridge 的主要代码如下:
struct bridge {
......
const struct ovsrec_bridge *cfg;
/* OpenFlow switch processing. */
struct ofproto *ofproto; /* OpenFlow switch. */
/* Bridge ports. */
struct hmap ports; /* "struct port"s indexed by name. */
struct hmap ifaces; /* "struct iface"s indexed by ofp_port. */
......
};
(2)ofproto
如下图所示,这也是一个交换机。
对于 Open vSwitch 的 ofproto 结构体而言,它描述的是上面这样的一个交换机:在 bridge 中的功能它基本都有,并且它还有许多代码实现上的细节,比如详细的描述信息和设置参数、OpenFlow 协议的具体实现、匹配规则和相应转发模块的调用。ofproto 的主要代码如下:
struct ofproto {
......
const struct ofproto_class *ofproto_class;
......
/* Settings. */
uint64_t fallback_dpid; /* Datapath ID if no better choice found. */
uint64_t datapath_id; /* Datapath ID. */
......
char *mfr_desc; /* Manufacturer (NULL for default). */
char *hw_desc; /* Hardware (NULL for default). */
char *sw_desc; /* Software version (NULL for default). */
char *serial_desc; /* Serial number (NULL for default). */
char *dp_desc; /* Datapath description (NULL for default). */
enum ofputil_frag_handling frag_handling;
/* Datapath. */
struct hmap ports; /* Contains "struct ofport"s. */
......
/* Flow tables. */
long long int eviction_group_timer; /* For rate limited reheapification. */
struct oftable *tables;
int n_tables;
ovs_version_t tables_version; /* Controls which rules are visible to table lookups. */
......
/* Meter table. */
struct ofputil_meter_features meter_features;
struct hmap meters; /* uint32_t indexed 'struct meter *'. */
uint32_t slowpath_meter_id; /* Datapath slowpath meter. UINT32_MAX if not defined. */
uint32_t controller_meter_id; /* Datapath controller meter. UINT32_MAX if not defined. */
/* OpenFlow connections. */
struct connmgr *connmgr;
int min_mtu; /* Current MTU of non-internal ports. */
/* Groups. */
struct cmap groups; /* Contains "struct ofgroup"s. */
uint32_t n_groups[4] OVS_GUARDED; /* # of existing groups of each type. */
struct ofputil_group_features ogf;
/* Tunnel TLV mapping table. */
OVSRCU_TYPE(struct tun_table *) metadata_tab;
......
};
(3)bridge vs. ofproto
所以虽然 bridge 和 ofproto 都是对 Open vSwitch 交换机的描述,但是它们是从不同的角度进行描述的,也就有着不同的侧重点和适用对象。
bridge 描述的是交换机外面的壳子,留出端口作为外部交互的节点,是给用户看的。用户通过 vsctl 等工具来实现对 bridge 的管理和使用。
ofproto 描述的是交换机的内部实现。当然如果要阐述交换机内部实现的所有细节仅仅一个 ofproto 是不够的,所以它提供了许多功能调用,对接更底层的内容。本质上 ofproto 是给操作系统看的,操作系统通过 ofproto 和相应的底层模块来实现交换机的功能(所以说从 ofproto 这里开始才是真正干活的部分)。
在 Open vSwitch 中 bridge 和 ofproto 是一一对应的关系,用户每创建一个 bridge 系统都会相应地创建一个 ofproto 用来负责具体的功能实现(这个动作由 ovs-vswitchd 守护进程负责)。
可以通过上图更形象地看出二者的关系:其中 ovs-vswitchd 维护 bridge,而 ofproto 会和 OpenFlow 控制器相连,还会调用更底层的模块(如 netdev 网络设备相关的模块),用于对 bridge 做具体的功能实现。
二、Port、Interface 和 ofprot 的区别
交换机的主要工作是数据包的转发,所以需要添加端口才能具有实际的作用。Open vSwitch 中使用 port 和 ofprot 来描述端口,分别对应 bridge 和 ofproto。二者的区别类似于 bridge 和 ofproto 的区别,它们是对端口的不同角度的描述, port 更贴近用户而 ofprot 更贴近底层。
在 bridge 中还有一个叫 iface 的结构,翻译为 接口 但其实可以当作更详细的端口来理解。换句话说,port 代表网桥端口的一个更高级别的抽象,而 iface 则代表一个具体的网络接口,在 iface 中保存了网络接口的各种属性和状态信息,而 port 则管理和协调多个 iface 的行为。一般而言 port 和 iface 二者是一对一的关系,但存在一种聚合(bond)的情况,此时可以把多个 iface 捆绑在一起然后归属到同一个 port 实现一对多的映射。
结语:
由于本人水平有限,以上内容如有不足之处欢迎大家指正(评论区/私信均可)。
参考资料:
Open vSwitch 源码阅读笔记(4)网桥 Bridge 相关的结构-优快云博客