datapath: Don't call genlmsg_reply() under rcu_read_lock().
[openvswitch] / vswitchd / bridge.c
index 4f20e804ac3887273b61363162cc0dd9539fa0c0..58053056ac04dc48b9e24e8a1b6489bcc6871a67 100644 (file)
@@ -401,7 +401,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
 
             port_configure(port);
 
-            HMAP_FOR_EACH (iface, ofp_port_node, &br->ifaces) {
+            LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
                 iface_configure_cfm(iface);
                 iface_configure_qos(iface, port->cfg->qos);
                 iface_set_mac(iface);
@@ -1216,17 +1216,19 @@ static bool
 iface_refresh_cfm_stats(struct iface *iface)
 {
     const struct ovsrec_interface *cfg = iface->cfg;
-    const struct cfm *cfm;
     bool changed = false;
+    int fault;
 
-    cfm = ofproto_port_get_cfm(iface->port->bridge->ofproto, iface->ofp_port);
+    fault = ofproto_port_get_cfm_fault(iface->port->bridge->ofproto,
+                                       iface->ofp_port);
 
-    if (!cfm) {
+    if (fault < 0) {
         return false;
     }
 
-    if (cfg->n_cfm_fault != 1 || cfg->cfm_fault[0] != cfm->fault) {
-        ovsrec_interface_set_cfm_fault(cfg, &cfm->fault, 1);
+    if (cfg->n_cfm_fault != 1 || cfg->cfm_fault[0] != fault) {
+        bool fault_bool = fault;
+        ovsrec_interface_set_cfm_fault(cfg, &fault_bool, 1);
         changed = true;
     }
 
@@ -1250,30 +1252,25 @@ iface_refresh_lacp_stats(struct iface *iface)
 static void
 iface_refresh_stats(struct iface *iface)
 {
-    struct iface_stat {
-        char *name;
-        int offset;
-    };
-    static const struct iface_stat iface_stats[] = {
-        { "rx_packets", offsetof(struct netdev_stats, rx_packets) },
-        { "tx_packets", offsetof(struct netdev_stats, tx_packets) },
-        { "rx_bytes", offsetof(struct netdev_stats, rx_bytes) },
-        { "tx_bytes", offsetof(struct netdev_stats, tx_bytes) },
-        { "rx_dropped", offsetof(struct netdev_stats, rx_dropped) },
-        { "tx_dropped", offsetof(struct netdev_stats, tx_dropped) },
-        { "rx_errors", offsetof(struct netdev_stats, rx_errors) },
-        { "tx_errors", offsetof(struct netdev_stats, tx_errors) },
-        { "rx_frame_err", offsetof(struct netdev_stats, rx_frame_errors) },
-        { "rx_over_err", offsetof(struct netdev_stats, rx_over_errors) },
-        { "rx_crc_err", offsetof(struct netdev_stats, rx_crc_errors) },
-        { "collisions", offsetof(struct netdev_stats, collisions) },
-    };
-    enum { N_STATS = ARRAY_SIZE(iface_stats) };
-    const struct iface_stat *s;
-
-    char *keys[N_STATS];
-    int64_t values[N_STATS];
-    int n;
+#define IFACE_STATS                             \
+    IFACE_STAT(rx_packets,      "rx_packets")   \
+    IFACE_STAT(tx_packets,      "tx_packets")   \
+    IFACE_STAT(rx_bytes,        "rx_bytes")     \
+    IFACE_STAT(tx_bytes,        "tx_bytes")     \
+    IFACE_STAT(rx_dropped,      "rx_dropped")   \
+    IFACE_STAT(tx_dropped,      "tx_dropped")   \
+    IFACE_STAT(rx_errors,       "rx_errors")    \
+    IFACE_STAT(tx_errors,       "tx_errors")    \
+    IFACE_STAT(rx_frame_errors, "rx_frame_err") \
+    IFACE_STAT(rx_over_errors,  "rx_over_err")  \
+    IFACE_STAT(rx_crc_errors,   "rx_crc_err")   \
+    IFACE_STAT(collisions,      "collisions")
+
+#define IFACE_STAT(MEMBER, NAME) NAME,
+    static char *keys[] = { IFACE_STATS };
+#undef IFACE_STAT
+    int64_t values[ARRAY_SIZE(keys)];
+    int i;
 
     struct netdev_stats stats;
 
@@ -1285,17 +1282,15 @@ iface_refresh_stats(struct iface *iface)
      * all-1s, and we will deal with that correctly below. */
     netdev_get_stats(iface->netdev, &stats);
 
-    n = 0;
-    for (s = iface_stats; s < &iface_stats[N_STATS]; s++) {
-        uint64_t value = *(uint64_t *) (((char *) &stats) + s->offset);
-        if (value != UINT64_MAX) {
-            keys[n] = s->name;
-            values[n] = value;
-            n++;
-        }
-    }
+    /* Copy statistics into values[] array. */
+    i = 0;
+#define IFACE_STAT(MEMBER, NAME) values[i++] = stats.MEMBER;
+    IFACE_STATS;
+#undef IFACE_STAT
+    assert(i == ARRAY_SIZE(keys));
 
-    ovsrec_interface_set_statistics(iface->cfg, keys, values, n);
+    ovsrec_interface_set_statistics(iface->cfg, keys, values, ARRAY_SIZE(keys));
+#undef IFACE_STATS
 }
 
 static void
@@ -2483,24 +2478,26 @@ static void
 iface_configure_cfm(struct iface *iface)
 {
     const struct ovsrec_interface *cfg = iface->cfg;
-    struct cfm cfm;
+    struct cfm_settings s;
+    uint16_t remote_mpid;
 
     if (!cfg->n_cfm_mpid || !cfg->n_cfm_remote_mpid) {
         ofproto_port_clear_cfm(iface->port->bridge->ofproto, iface->ofp_port);
         return;
     }
 
-    cfm.mpid = *cfg->cfm_mpid;
-    cfm.name = iface->name;
-    cfm.interval = atoi(get_interface_other_config(iface->cfg,
-                                                   "cfm_interval", "0"));
+    s.mpid = *cfg->cfm_mpid;
+    remote_mpid = *cfg->cfm_remote_mpid;
+    s.remote_mpids = &remote_mpid;
+    s.n_remote_mpids = 1;
 
-    if (cfm.interval <= 0) {
-        cfm.interval = 1000;
+    s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
+                                                 "0"));
+    if (s.interval <= 0) {
+        s.interval = 1000;
     }
 
-    ofproto_port_set_cfm(iface->port->bridge->ofproto, iface->ofp_port,
-                         &cfm, *cfg->cfm_remote_mpid);
+    ofproto_port_set_cfm(iface->port->bridge->ofproto, iface->ofp_port, &s);
 }
 
 /* Read carrier or miimon status directly from 'iface''s netdev, according to