-static int
-bridge_run_one(struct bridge *br)
-{
- size_t i;
- int error;
-
- error = ofproto_run1(br->ofproto);
- if (error) {
- return error;
- }
-
- mac_learning_run(br->ml, ofproto_get_revalidate_set(br->ofproto));
-
- for (i = 0; i < br->n_ports; i++) {
- port_run(br->ports[i]);
- }
-
- error = ofproto_run2(br->ofproto, br->flush);
- br->flush = false;
-
- return error;
-}
-
-static size_t
-bridge_get_controllers(const struct bridge *br,
- struct ovsrec_controller ***controllersp)
-{
- struct ovsrec_controller **controllers;
- size_t n_controllers;
-
- controllers = br->cfg->controller;
- n_controllers = br->cfg->n_controller;
-
- if (n_controllers == 1 && !strcmp(controllers[0]->target, "none")) {
- controllers = NULL;
- n_controllers = 0;
- }
-
- if (controllersp) {
- *controllersp = controllers;
- }
- return n_controllers;
-}
-
-static void
-bridge_reconfigure_one(struct bridge *br)
-{
- struct shash old_ports, new_ports;
- struct svec snoops, old_snoops;
- struct shash_node *node;
- enum ofproto_fail_mode fail_mode;
- size_t i;
-
- /* Collect old ports. */
- shash_init(&old_ports);
- for (i = 0; i < br->n_ports; i++) {
- shash_add(&old_ports, br->ports[i]->name, br->ports[i]);
- }
-
- /* Collect new ports. */
- shash_init(&new_ports);
- for (i = 0; i < br->cfg->n_ports; i++) {
- const char *name = br->cfg->ports[i]->name;
- if (!shash_add_once(&new_ports, name, br->cfg->ports[i])) {
- VLOG_WARN("bridge %s: %s specified twice as bridge port",
- br->name, name);
- }
- }
-
- /* If we have a controller, then we need a local port. Complain if the
- * user didn't specify one.
- *
- * XXX perhaps we should synthesize a port ourselves in this case. */
- if (bridge_get_controllers(br, NULL)) {
- char local_name[IF_NAMESIZE];
- int error;
-
- error = dpif_port_get_name(br->dpif, ODPP_LOCAL,
- local_name, sizeof local_name);
- if (!error && !shash_find(&new_ports, local_name)) {
- VLOG_WARN("bridge %s: controller specified but no local port "
- "(port named %s) defined",
- br->name, local_name);
- }
- }
-
- /* Get rid of deleted ports.
- * Get rid of deleted interfaces on ports that still exist. */
- SHASH_FOR_EACH (node, &old_ports) {
- struct port *port = node->data;
- const struct ovsrec_port *port_cfg;
-
- port_cfg = shash_find_data(&new_ports, node->name);
- if (!port_cfg) {
- port_destroy(port);
- } else {
- port_del_ifaces(port, port_cfg);
- }
- }
-
- /* Create new ports.
- * Add new interfaces to existing ports.
- * Reconfigure existing ports. */
- SHASH_FOR_EACH (node, &new_ports) {
- struct port *port = shash_find_data(&old_ports, node->name);
- if (!port) {
- port = port_create(br, node->name);
- }
-
- port_reconfigure(port, node->data);
- if (!port->n_ifaces) {
- VLOG_WARN("bridge %s: port %s has no interfaces, dropping",
- br->name, port->name);
- port_destroy(port);
- }
- }
- shash_destroy(&old_ports);
- shash_destroy(&new_ports);
-
- /* Set the fail-mode */
- fail_mode = !br->cfg->fail_mode
- || !strcmp(br->cfg->fail_mode, "standalone")
- ? OFPROTO_FAIL_STANDALONE
- : OFPROTO_FAIL_SECURE;
- if (ofproto_get_fail_mode(br->ofproto) != fail_mode
- && !ofproto_has_primary_controller(br->ofproto)) {
- ofproto_flush_flows(br->ofproto);
- }
- ofproto_set_fail_mode(br->ofproto, fail_mode);
-
- /* Delete all flows if we're switching from connected to standalone or vice
- * versa. (XXX Should we delete all flows if we are switching from one
- * controller to another?) */
-
- /* Configure OpenFlow controller connection snooping. */
- svec_init(&snoops);
- svec_add_nocopy(&snoops, xasprintf("punix:%s/%s.snoop",
- ovs_rundir(), br->name));
- svec_init(&old_snoops);
- ofproto_get_snoops(br->ofproto, &old_snoops);
- if (!svec_equal(&snoops, &old_snoops)) {
- ofproto_set_snoops(br->ofproto, &snoops);
- }
- svec_destroy(&snoops);
- svec_destroy(&old_snoops);
-
- mirror_reconfigure(br);
-}
-
-/* Initializes 'oc' appropriately as a management service controller for
- * 'br'.
- *
- * The caller must free oc->target when it is no longer needed. */
-static void
-bridge_ofproto_controller_for_mgmt(const struct bridge *br,
- struct ofproto_controller *oc)
-{
- oc->target = xasprintf("punix:%s/%s.mgmt", ovs_rundir(), br->name);
- oc->max_backoff = 0;
- oc->probe_interval = 60;
- oc->band = OFPROTO_OUT_OF_BAND;
- oc->rate_limit = 0;
- oc->burst_limit = 0;
-}
-
-/* Converts ovsrec_controller 'c' into an ofproto_controller in 'oc'. */
-static void
-bridge_ofproto_controller_from_ovsrec(const struct ovsrec_controller *c,
- struct ofproto_controller *oc)
-{
- oc->target = c->target;
- oc->max_backoff = c->max_backoff ? *c->max_backoff / 1000 : 8;
- oc->probe_interval = c->inactivity_probe ? *c->inactivity_probe / 1000 : 5;
- oc->band = (!c->connection_mode || !strcmp(c->connection_mode, "in-band")
- ? OFPROTO_IN_BAND : OFPROTO_OUT_OF_BAND);
- oc->rate_limit = c->controller_rate_limit ? *c->controller_rate_limit : 0;
- oc->burst_limit = (c->controller_burst_limit
- ? *c->controller_burst_limit : 0);
-}
-
-/* Configures the IP stack for 'br''s local interface properly according to the
- * configuration in 'c'. */
-static void
-bridge_configure_local_iface_netdev(struct bridge *br,
- struct ovsrec_controller *c)
-{
- struct netdev *netdev;
- struct in_addr mask, gateway;
-
- struct iface *local_iface;
- struct in_addr ip;
-
- /* If there's no local interface or no IP address, give up. */
- local_iface = iface_from_dp_ifidx(br, ODPP_LOCAL);
- if (!local_iface || !c->local_ip || !inet_aton(c->local_ip, &ip)) {
- return;
- }
-
- /* Bring up the local interface. */
- netdev = local_iface->netdev;
- netdev_turn_flags_on(netdev, NETDEV_UP, true);
-
- /* Configure the IP address and netmask. */
- if (!c->local_netmask
- || !inet_aton(c->local_netmask, &mask)
- || !mask.s_addr) {
- mask.s_addr = guess_netmask(ip.s_addr);
- }
- if (!netdev_set_in4(netdev, ip, mask)) {
- VLOG_INFO("bridge %s: configured IP address "IP_FMT", netmask "IP_FMT,
- br->name, IP_ARGS(&ip.s_addr), IP_ARGS(&mask.s_addr));
- }
-
- /* Configure the default gateway. */
- if (c->local_gateway
- && inet_aton(c->local_gateway, &gateway)
- && gateway.s_addr) {
- if (!netdev_add_router(netdev, gateway)) {
- VLOG_INFO("bridge %s: configured gateway "IP_FMT,
- br->name, IP_ARGS(&gateway.s_addr));