cfm: Immediately signal a fault upon receiving an unexpected MPID.
[openvswitch] / vswitchd / bridge.c
index c8b50d7136bb7750a997290f4de926860effe28f..b4bacc9a33f3648a8ab8fe6e149900ca05eb18d2 100644 (file)
@@ -185,6 +185,7 @@ struct port {
     /* LACP information. */
     struct lacp *lacp;          /* LACP object. NULL if LACP is disabled. */
     bool lacp_active;           /* True if LACP is active */
+    bool lacp_fast;             /* True if LACP is in fast mode. */
     uint16_t lacp_priority;     /* LACP system priority. */
 
     /* SLB specific bonding info. */
@@ -306,7 +307,8 @@ static void iface_update_qos(struct iface *, const struct ovsrec_qos *);
 static void iface_update_cfm(struct iface *);
 static void iface_refresh_cfm_stats(struct iface *iface);
 static void iface_send_packet(struct iface *, struct ofpbuf *packet);
-static void iface_update_carrier(struct iface *, bool carrier);
+static void iface_update_carrier(struct iface *);
+static bool iface_get_carrier(const struct iface *);
 
 static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
                                    struct shash *);
@@ -725,7 +727,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
                 /* Update 'iface'. */
                 if (iface) {
                     iface->netdev = netdev;
-                    iface->enabled = netdev_get_carrier(iface->netdev);
+                    iface->enabled = iface_get_carrier(iface);
                     iface->up = iface->enabled;
                 }
             } else if (iface && iface->netdev) {
@@ -1193,8 +1195,7 @@ iface_refresh_status(struct iface *iface)
 
 
     ovsrec_interface_set_link_state(iface->cfg,
-                                    netdev_get_carrier(iface->netdev)
-                                    ? "up" : "down");
+                                    iface_get_carrier(iface) ? "up" : "down");
 
     error = netdev_get_mtu(iface->netdev, &mtu);
     if (!error && mtu != INT_MAX) {
@@ -3881,7 +3882,7 @@ port_run(struct port *port)
 
             iface = port_lookup_iface(port, devname);
             if (iface) {
-                iface_update_carrier(iface, netdev_get_carrier(iface->netdev));
+                iface_update_carrier(iface);
             }
             free(devname);
         }
@@ -3889,7 +3890,7 @@ port_run(struct port *port)
 
         for (i = 0; i < port->n_ifaces; i++) {
             struct iface *iface = port->ifaces[i];
-            iface_update_carrier(iface, netdev_get_miimon(iface->netdev));
+            iface_update_carrier(iface);
         }
         port->miimon_next_update = time_msec() + port->miimon_interval;
     }
@@ -4132,6 +4133,9 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
     }
     shash_destroy(&new_ifaces);
 
+    port->lacp_fast = !strcmp(get_port_other_config(cfg, "lacp-time", "slow"),
+                             "fast");
+
     lacp_priority =
         atoi(get_port_other_config(cfg, "lacp-system-priority", "0"));
 
@@ -4290,7 +4294,7 @@ port_update_lacp(struct port *port)
 
         lacp_configure(port->lacp, port->name,
                        port->bridge->ea, port->lacp_priority,
-                       port->lacp_active);
+                       port->lacp_active, port->lacp_fast);
 
         for (i = 0; i < port->n_ifaces; i++) {
             struct iface *iface = port->ifaces[i];
@@ -4585,8 +4589,9 @@ iface_delete_queues(unsigned int queue_id,
 }
 
 static void
-iface_update_carrier(struct iface *iface, bool carrier)
+iface_update_carrier(struct iface *iface)
 {
+    bool carrier = iface_get_carrier(iface);
     if (carrier == iface->up) {
         return;
     }
@@ -4684,6 +4689,18 @@ iface_update_cfm(struct iface *iface)
         iface->cfm = NULL;
     }
 }
+
+/* Read carrier or miimon status directly from 'iface''s netdev, according to
+ * how 'iface''s port is configured.
+ *
+ * Returns true if 'iface' is up, false otherwise. */
+static bool
+iface_get_carrier(const struct iface *iface)
+{
+    return (iface->port->monitor
+            ? netdev_get_carrier(iface->netdev)
+            : netdev_get_miimon(iface->netdev));
+}
 \f
 /* Port mirroring. */