bond: Reconfigure flows when bond mode changes.
[sliver-openvswitch.git] / vswitchd / bridge.c
index 07daacd..26b4f70 100644 (file)
@@ -283,16 +283,54 @@ bridge_init(const char *remote)
     ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg);
     ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics);
     ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_external_ids);
+    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_ovs_version);
+    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_db_version);
+    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_type);
+    ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_version);
 
+    ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_id);
     ovsdb_idl_omit(idl, &ovsrec_bridge_col_external_ids);
 
     ovsdb_idl_omit(idl, &ovsrec_port_col_external_ids);
     ovsdb_idl_omit(idl, &ovsrec_port_col_fake_bridge);
 
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_admin_state);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_duplex);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_speed);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_state);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_mtu);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_ofport);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_statistics);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_status);
     ovsdb_idl_omit(idl, &ovsrec_interface_col_external_ids);
 
+    ovsdb_idl_omit_alert(idl, &ovsrec_controller_col_is_connected);
+    ovsdb_idl_omit_alert(idl, &ovsrec_controller_col_role);
+    ovsdb_idl_omit_alert(idl, &ovsrec_controller_col_status);
+    ovsdb_idl_omit(idl, &ovsrec_controller_col_external_ids);
+
+    ovsdb_idl_omit_alert(idl, &ovsrec_maintenance_point_col_fault);
+
+    ovsdb_idl_omit_alert(idl, &ovsrec_monitor_col_fault);
+
+    ovsdb_idl_omit(idl, &ovsrec_qos_col_external_ids);
+
+    ovsdb_idl_omit(idl, &ovsrec_queue_col_external_ids);
+
+    ovsdb_idl_omit(idl, &ovsrec_mirror_col_external_ids);
+
+    ovsdb_idl_omit(idl, &ovsrec_netflow_col_external_ids);
+
+    ovsdb_idl_omit(idl, &ovsrec_sflow_col_external_ids);
+
+    ovsdb_idl_omit(idl, &ovsrec_manager_col_external_ids);
+    ovsdb_idl_omit(idl, &ovsrec_manager_col_inactivity_probe);
+    ovsdb_idl_omit(idl, &ovsrec_manager_col_is_connected);
+    ovsdb_idl_omit(idl, &ovsrec_manager_col_max_backoff);
+    ovsdb_idl_omit(idl, &ovsrec_manager_col_status);
+
+    ovsdb_idl_omit(idl, &ovsrec_ssl_col_external_ids);
+
     /* Register unixctl commands. */
     unixctl_command_register("fdb/show", bridge_unixctl_fdb_show, NULL);
     unixctl_command_register("cfm/show", cfm_unixctl_show, NULL);
@@ -855,8 +893,13 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         iterate_and_prune_ifaces(br, set_iface_properties, NULL);
     }
 
+    /* Some reconfiguration operations require the bridge to have been run at
+     * least once.  */
     LIST_FOR_EACH (br, node, &all_bridges) {
         struct iface *iface;
+
+        bridge_run_one(br);
+
         HMAP_FOR_EACH (iface, dp_ifidx_node, &br->ifaces) {
             iface_update_cfm(iface);
         }
@@ -2651,11 +2694,37 @@ bridge_account_checkpoint_ofhook_cb(void *br_)
     }
 }
 
+static uint16_t
+bridge_autopath_ofhook_cb(const struct flow *flow, uint32_t ofp_port,
+                          tag_type *tags, void *br_)
+{
+    struct bridge *br = br_;
+    uint16_t odp_port = ofp_port_to_odp_port(ofp_port);
+    struct port *port = port_from_dp_ifidx(br, odp_port);
+    uint16_t ret;
+
+    if (!port) {
+        ret = ODPP_NONE;
+    } else if (list_is_short(&port->ifaces)) {
+        ret = odp_port;
+    } else {
+        struct iface *iface;
+
+        /* Autopath does not support VLAN hashing. */
+        iface = bond_choose_output_slave(port->bond, flow,
+                                         OFP_VLAN_NONE, tags);
+        ret = iface ? iface->dp_ifidx : ODPP_NONE;
+    }
+
+    return odp_port_to_ofp_port(ret);
+}
+
 static struct ofhooks bridge_ofhooks = {
     bridge_normal_ofhook_cb,
     bridge_special_ofhook_cb,
     bridge_account_flow_ofhook_cb,
     bridge_account_checkpoint_ofhook_cb,
+    bridge_autopath_ofhook_cb,
 };
 \f
 /* Port functions. */
@@ -3038,7 +3107,9 @@ port_reconfigure_bond(struct port *port)
     if (!port->bond) {
         port->bond = bond_create(&s);
     } else {
-        bond_reconfigure(port->bond, &s);
+        if (bond_reconfigure(port->bond, &s)) {
+            bridge_flush(port->bridge);
+        }
     }
 
     LIST_FOR_EACH (iface, port_elem, &port->ifaces) {