openflow连接有两个用途: 1)与controller连接;2)提供给ovs-ofctl工具配置流表等。
我们先看连接的初始化过程,配置入口是bridge_reconfigure函数。
1、bridge_reconfigure函数
collect_in_band_managers(ovs_cfg, &managers, &n_managers); //收集配置的manager信息
HMAP_FOR_EACH (br, node, &all_bridges) {
struct port *port;
/* We need the datapath ID early to allow LACP ports to use it as the
* default system ID. */
bridge_configure_datapath_id(br);
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
struct iface *iface;
port_configure(port);
LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
iface_set_ofport(iface->cfg, iface->ofp_port);
/* Clear eventual previous errors */
ovsrec_interface_set_error(iface->cfg, NULL);
iface_configure_cfm(iface);
iface_configure_qos(iface, port->cfg->qos);
iface_set_mac(br, port, iface);
ofproto_port_set_bfd(br->ofproto, iface->ofp_port,
&iface->cfg->bfd);
ofproto_port_set_lldp(br->ofproto, iface->ofp_port,
&iface->cfg->lldp);
}
}
bridge_configure_mirrors(br);
bridge_configure_forward_bpdu(br);
bridge_configure_mac_table(br);
bridge_configure_mcast_snooping(br);
bridge_configure_remotes(br, managers, n_managers); //配置入口
bridge_configure_netflow(br);
bridge_configure_sflow(br, &sflow_bridge_number);
bridge_configure_ipfix(br);
bridge_configure_spanning_tree(br);
bridge_configure_tables(br);
bridge_configure_dp_desc(br);
bridge_configure_aa(br);
}
2、bridge_configure_remote函数
static void
bridge_configure_remotes(struct bridge *br,
const struct sockaddr_in *managers, size_t n_managers)
{
bool disable_in_band;
struct ovsrec_controller **controllers;
size_t n_controllers;
enum ofproto_fail_mode fail_mode;
struct ofproto_controller *ocs;
size_t n_ocs;
size_t i;
/* Check if we should disable in-band control on this bridge. */
disable_in_band = smap_get_bool(&br->cfg->other_config, "disable-in-band",
false);
/* Set OpenFlow queue ID for in-band control. */
ofproto_set_in_band_queue(br->ofproto,
smap_get_int(&br->cfg->other_config,
"in-band-queue", -1));
if (disable_in_band) {
ofproto_set_extra_in_band_remotes(br->ofproto, NULL, 0);
} else {
ofproto_set_extra_in_band_remotes(br->ofproto, managers, n_managers);
}
n_controllers = bridge_get_controllers(br, &controllers); //获取controller配置信息
ocs = xmalloc((n_controllers + 1) * sizeof *ocs);
n_ocs = 0;
bridge_ofproto_controller_for_mgmt(br, &ocs[n_ocs++]); //第1个,本质上不是controller,是作为管理供ovs-ofctl工具进行连接,使用punix
for (i = 0; i < n_controllers; i++) {
struct ovsrec_controller *c = controllers[i];
if (!strncmp(c->target, "punix:", 6)
|| !strncmp(c->target, "unix:", 5)) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
char *whitelist;