一、网桥 Bridge 的定义
在计算机网络中,网桥 Bridge 是连接两个或多个局域网的网络设备,它工作在数据链路层,根据数据帧的目标 MAC 地址,将数据从一个网段转发到另一个网段。在 Linux 中,Linux Bridge 是 Linux 内核中的一个虚拟网络设备,它可以在 Linux 系统上模拟传统物理网桥的功能,主要用于在虚拟环境中连接不同的网络接口和虚拟机。在 Open vSwitch 中,Bridge 也代表一个虚拟网桥,可以简单理解为 Open vSwitch 的 Bridge 是 Linux Bridge 的功能加强版。
二、Bridge 结构体
Bridge 相关的结构体内容都定义在 ovs-main/vswitchd/bridge.c 文件中:
struct bridge {
struct hmap_node node; /* In 'all_bridges'. */
char *name; /* User-specified arbitrary name. */
char *type; /* Datapath type. */
struct eth_addr ea; /* Bridge Ethernet Address. */
struct eth_addr default_ea; /* Default MAC. */
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. */
struct hmap iface_by_name; /* "struct iface"s indexed by name. */
/* Port mirroring. */
struct hmap mirrors; /* "struct mirror" indexed by UUID. */
/* Auto Attach */
struct hmap mappings; /* "struct" indexed by UUID */
/* Used during reconfiguration. */
struct shash wanted_ports;
/* Synthetic local port if necessary. */
struct ovsrec_port synth_local_port;
struct ovsrec_interface synth_local_iface;
struct ovsrec_interface *synth_local_ifacep;
};
首先可以看到,bridge 本身就是哈希表 all_bridges 的一个元素,其中 all_bridges 定义为:
/* All bridges, indexed by name. */
static struct hmap all_bridges = HMAP_INITIALIZER(&all_bridges);
所以 node 这个成员变量的作用主要是将 bridge 结构体链接到哈希表 all_bridges 中,以便于快速地查找和管理所有的网桥。
接下来用 name 和 type 两个字符串记录网桥名称和数据路径类型,用 eth_addr 结构存储网桥的 MAC 地址 ea 和默认 MAC 地址 default_ea,其中 MAC 地址的结构体 eth_addr 定义在 ovs-main/include/openvswitch/types.h 头文件中:
/* Using this struct instead of a bare array makes an ethernet address field assignable.
* The size of the array is also part of the type, so it is easier to deal with. */
struct eth_addr {
union {
uint8_t ea[6];
ovs_be16 be16[3];
};
};
此处分别以字节和整数这两种方式存储 MAC 地址。
const struct ovsrec_bridge *cfg 指向与这个网桥对应的 OVSDB 配置记录。
struct ofproto *ofproto 用于指向与这个网桥对应的 ofproto 实例。
成员变量 ports、ifaces、iface_by_name、mirrors 和 mappings 分别定义了端口、接口、镜像等相关的内容,并以 hmap 哈希表的形式存储。(关于 hmap 哈希表可以参考 OVS 中哈希表的实现 这篇文章)
struct shash wanted_ports 在网桥重新配置期间使用,用于存储所需的端口。shash 相关结构体定义在 ovs-main/include/openvswitch/shash.h 头文件中:
struct shash_node {
struct hmap_node node;
char *name;
void *data;
};
struct shash {
struct hmap map;
};
可以看出,其本质仍然是 hmap 哈希表,只是对字符串键做了专门的适配。
最后,成员变量 synth_local_port、synth_local_iface 和 *synth_local_ifacep 用于从数据库中同步本地端口和接口的相关信息(此处我对于 synthetic 这个词存疑)。
三、端口 Port
端口 Port 是收发数据包的单元(参考物理网桥的端口概念),端口收到的数据包会经过流规则的处理,发往其他端口。注意每个端口 Port 都要隶属于一个特定的网桥 Bridge。
struct port {
struct hmap_node hmap_node; /* Element in struct bridge's "ports" hmap. */
struct bridge *bridge;
char *name;
const struct ovsrec_port *cfg;
/* An ordinary bridge port has 1 interface.
* A bridge port for bonding has at least 2 interfaces. */
struct ovs_list ifaces; /* List of "struct iface"s. */
};
四、接口 Interface
接口 Interface 是 Open vSwitch 与外部交换数据包的组件,可以简单理解为操作系统的一块网卡,可以是真实的也可以是虚拟的。通常情况 Port 和 Interface 是一对一的关系(但是一对多也是可以的),并且每个接口 Interface 也都要隶属于一个特定的网桥 Bridge。
struct iface {
/* These members are always valid.
* They are immutable: they never change between iface_create() and iface_destroy(). */
struct ovs_list port_elem; /* Element in struct port's "ifaces" list. */
struct hmap_node name_node; /* In struct bridge's "iface_by_name" hmap. */
struct hmap_node ofp_port_node; /* In struct bridge's "ifaces" hmap. */
struct port *port; /* Containing port. */
char *name; /* Host network device name. */
struct netdev *netdev; /* Network device. */
ofp_port_t ofp_port; /* OpenFlow port number. */
uint64_t change_seq;
/* These members are valid only within bridge_reconfigure(). */
const char *type; /* Usually same as cfg->type. */
const struct ovsrec_interface *cfg;
};
结语:
由于本人水平有限,以上内容如有不足之处欢迎大家指正(评论区/私信均可)。