ovs-ofctl: Fix usage message for "monitor" command.
[openvswitch] / vswitchd / bridge.c
index 24db5b5e6fe7b49e96c4ee66389c0e97968f8dfe..354d4d89452a46adef4771dbbf478cb6a23d35de 100644 (file)
@@ -122,7 +122,8 @@ struct port {
     struct bridge *bridge;
     size_t port_idx;
     int vlan;                   /* -1=trunk port, else a 12-bit VLAN ID. */
-    unsigned long *trunks;      /* Bitmap of trunked VLANs, if 'vlan' == -1. */
+    unsigned long *trunks;      /* Bitmap of trunked VLANs, if 'vlan' == -1.
+                                 * NULL if all VLANs are trunked. */
     char *name;
 
     /* An ordinary bridge port has 1 interface.
@@ -177,6 +178,7 @@ struct bridge {
     struct port **ports;
     size_t n_ports, allocated_ports;
     struct shash iface_by_name; /* "struct iface"s indexed by name. */
+    struct shash port_by_name;  /* "struct port"s indexed by name. */
 
     /* Bonding. */
     bool has_bonded_ports;
@@ -1208,6 +1210,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
 
     port_array_init(&br->ifaces);
 
+    shash_init(&br->port_by_name);
     shash_init(&br->iface_by_name);
 
     br->flush = false;
@@ -1238,6 +1241,7 @@ bridge_destroy(struct bridge *br)
         ofproto_destroy(br->ofproto);
         mac_learning_destroy(br->ml);
         port_array_destroy(&br->ifaces);
+        shash_destroy(&br->port_by_name);
         shash_destroy(&br->iface_by_name);
         free(br->ports);
         free(br->name);
@@ -2070,7 +2074,8 @@ dst_is_duplicate(const struct dst *dsts, size_t n_dsts,
 static bool
 port_trunks_vlan(const struct port *port, uint16_t vlan)
 {
-    return port->vlan < 0 && bitmap_is_set(port->trunks, vlan);
+    return (port->vlan < 0
+            && (!port->trunks || bitmap_is_set(port->trunks, vlan)));
 }
 
 static bool
@@ -3226,6 +3231,7 @@ port_create(struct bridge *br, const char *name)
                                sizeof *br->ports);
     }
     br->ports[br->n_ports++] = port;
+    shash_add_assert(&br->port_by_name, port->name, port);
 
     VLOG_INFO("created port %s on bridge %s", port->name, br->name);
     bridge_flush(br);
@@ -3350,7 +3356,7 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
 
     /* Get trunked VLANs. */
     trunks = NULL;
-    if (vlan < 0) {
+    if (vlan < 0 && cfg->n_trunks) {
         size_t n_errors;
         size_t i;
 
@@ -3369,17 +3375,14 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
                      port->name, cfg->n_trunks);
         }
         if (n_errors == cfg->n_trunks) {
-            if (n_errors) {
-                VLOG_ERR("port %s: no valid trunks, trunking all VLANs",
-                         port->name);
-            }
-            bitmap_set_multiple(trunks, 0, 4096, 1);
-        }
-    } else {
-        if (cfg->n_trunks) {
-            VLOG_ERR("port %s: ignoring trunks in favor of implicit vlan",
+            VLOG_ERR("port %s: no valid trunks, trunking all VLANs",
                      port->name);
+            bitmap_free(trunks);
+            trunks = NULL;
         }
+    } else if (vlan >= 0 && cfg->n_trunks) {
+        VLOG_ERR("port %s: ignoring trunks in favor of implicit vlan",
+                 port->name);
     }
     if (trunks == NULL
         ? port->trunks != NULL
@@ -3388,8 +3391,6 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
     }
     bitmap_free(port->trunks);
     port->trunks = trunks;
-
-    shash_destroy(&new_ifaces);
 }
 
 static void
@@ -3414,6 +3415,8 @@ port_destroy(struct port *port)
             iface_destroy(port->ifaces[port->n_ifaces - 1]);
         }
 
+        shash_find_and_delete_assert(&br->port_by_name, port->name);
+
         del = br->ports[port->port_idx] = br->ports[--br->n_ports];
         del->port_idx = port->port_idx;
 
@@ -3435,15 +3438,7 @@ port_from_dp_ifidx(const struct bridge *br, uint16_t dp_ifidx)
 static struct port *
 port_lookup(const struct bridge *br, const char *name)
 {
-    size_t i;
-
-    for (i = 0; i < br->n_ports; i++) {
-        struct port *port = br->ports[i];
-        if (!strcmp(port->name, name)) {
-            return port;
-        }
-    }
-    return NULL;
+    return shash_find_data(&br->port_by_name, name);
 }
 
 static struct iface *
@@ -3618,6 +3613,8 @@ iface_create(struct port *port, const struct ovsrec_interface *if_cfg)
     iface->netdev = NULL;
     iface->cfg = if_cfg;
 
+    shash_add_assert(&br->iface_by_name, iface->name, iface);
+
     /* Attempt to create the network interface in case it doesn't exist yet. */
     if (!iface_is_internal(br, iface->name)) {
         error = set_up_iface(if_cfg, iface, true);
@@ -3625,14 +3622,13 @@ iface_create(struct port *port, const struct ovsrec_interface *if_cfg)
             VLOG_WARN("could not create iface %s: %s", iface->name,
                       strerror(error));
 
+            shash_find_and_delete_assert(&br->iface_by_name, iface->name);
             free(iface->name);
             free(iface);
             return NULL;
         }
     }
 
-    shash_add_assert(&br->iface_by_name, iface->name, iface);
-
     if (port->n_ifaces >= port->allocated_ifaces) {
         port->ifaces = x2nrealloc(port->ifaces, &port->allocated_ifaces,
                                   sizeof *port->ifaces);