ovs-vsctl: Add options parsing infrastructure.
[openvswitch] / vswitchd / bridge.c
index 3028766cd93771ae96bd48b35897145f9b641a3b..205577738fe58e0b187b7a8539c6d50bd24d275d 100644 (file)
@@ -247,7 +247,8 @@ static bool vlan_is_mirrored(const struct mirror *m UNUSED, int vlan UNUSED)
 }
 #endif
 
-static struct iface *iface_create(struct port *, const char *name);
+static struct iface *iface_create(struct port *port, 
+                                  const struct ovsrec_interface *if_cfg);
 static void iface_destroy(struct iface *);
 static struct iface *iface_lookup(const struct bridge *, const char *name);
 static struct iface *iface_from_dp_ifidx(const struct bridge *,
@@ -421,24 +422,12 @@ set_up_iface(const struct ovsrec_interface *iface_cfg, bool create)
     return error;
 }
 
-static int
-create_iface(const struct ovsrec_interface *iface_cfg)
-{
-    return set_up_iface(iface_cfg, true);
-}
-
 static int
 reconfigure_iface(const struct ovsrec_interface *iface_cfg)
 {
     return set_up_iface(iface_cfg, false);
 }
 
-static void
-destroy_iface(const char *iface_name)
-{
-    netdev_destroy(iface_name);
-}
-
 
 /* iterate_and_prune_ifaces() callback function that opens the network device
  * for 'iface', if it is not already open, and retrieves the interface's MAC
@@ -562,7 +551,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
         const struct ovsrec_bridge *br_cfg = node->data;
         if (!shash_find_data(&old_br, br_name)) {
             br = bridge_create(br_name);
-            br->cfg = br_cfg;
+            if (br) {
+                br->cfg = br_cfg;
+            }
         }
     }
     shash_destroy(&old_br);
@@ -600,7 +591,6 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
                              p->devname, dpif_name(br->dpif),
                              strerror(retval));
                 }
-                destroy_iface(p->devname);
             }
         }
         shash_destroy(&want_ifaces);
@@ -640,17 +630,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
                 bool internal;
                 int error;
 
-                /* Attempt to create the network interface in case it
-                 * doesn't exist yet. */
-                error = iface ? create_iface(iface->cfg) : 0;
-                if (error) {
-                    VLOG_WARN("could not create iface %s: %s\n", if_name,
-                              strerror(error));
-                    continue;
-                }
-
                 /* Add to datapath. */
-                internal = !iface || iface_is_internal(br, if_name);
+                internal = iface_is_internal(br, if_name);
                 error = dpif_port_add(br->dpif, if_name,
                                       internal ? ODP_PORT_INTERNAL : 0, NULL);
                 if (error == EFBIG) {
@@ -712,7 +693,10 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
             if (!opts.active_timeout) {
                 opts.active_timeout = -1;
             } else if (opts.active_timeout < 0) {
-                opts.active_timeout = 0;
+                VLOG_WARN("bridge %s: active timeout interval set to negative "
+                          "value, using default instead (%d seconds)", br->name,
+                          NF_ACTIVE_TIMEOUT_DEFAULT);
+                opts.active_timeout = -1;
             }
 
             opts.add_id_to_iface = nf_cfg->add_id_to_interface;
@@ -1248,14 +1232,21 @@ bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg,
                       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_controller(ovs_cfg, br)) {
         char local_name[IF_NAMESIZE];
         int error;
 
         error = dpif_port_get_name(br->dpif, ODPP_LOCAL,
                                    local_name, sizeof local_name);
-        if (!error) {
-            shash_add_once(&new_ports, local_name, NULL);
+        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);
         }
     }
 
@@ -2997,12 +2988,11 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
     }
     SHASH_FOR_EACH (node, &new_ifaces) {
         const struct ovsrec_interface *if_cfg = node->data;
-        const char *if_name = node->name;
         struct iface *iface;
 
-        iface = shash_find_data(&old_ifaces, if_name);
+        iface = shash_find_data(&old_ifaces, if_cfg->name);
         if (!iface) {
-            iface = iface_create(port, if_name);
+            iface = iface_create(port, if_cfg);
         }
         iface->cfg = if_cfg;
     }
@@ -3285,9 +3275,11 @@ port_update_vlan_compat(struct port *port)
 /* Interface functions. */
 
 static struct iface *
-iface_create(struct port *port, const char *name)
+iface_create(struct port *port, const struct ovsrec_interface *if_cfg)
 {
     struct iface *iface;
+    char *name = if_cfg->name;
+    int error;
 
     iface = xzalloc(sizeof *iface);
     iface->port = port;
@@ -3307,6 +3299,14 @@ iface_create(struct port *port, const char *name)
         port->bridge->has_bonded_ports = true;
     }
 
+    /* Attempt to create the network interface in case it
+     * doesn't exist yet. */
+    error = set_up_iface(if_cfg, true);
+    if (error) {
+        VLOG_WARN("could not create iface %s: %s\n", iface->name,
+                strerror(error));
+    }
+
     VLOG_DBG("attached network device %s to port %s", iface->name, port->name);
 
     bridge_flush(port->bridge);
@@ -3331,8 +3331,6 @@ iface_destroy(struct iface *iface)
         del->port_ifidx = iface->port_ifidx;
 
         netdev_close(iface->netdev);
-        free(iface->name);
-        free(iface);
 
         if (del_active) {
             ofproto_revalidate(port->bridge->ofproto, port->active_iface_tag);
@@ -3340,6 +3338,10 @@ iface_destroy(struct iface *iface)
             bond_send_learning_packets(port);
         }
 
+        netdev_destroy(iface->name);
+        free(iface->name);
+        free(iface);
+
         bridge_flush(port->bridge);
     }
 }