bridge: Rate limit default address warnings.
[openvswitch] / utilities / ovs-vsctl.c
index 560d747a29a04f8f0daeb38b88144170cb08fb18..a5bd64741af72299f05b675260344c1c0b521a49 100644 (file)
@@ -41,7 +41,7 @@
 #include "stream-ssl.h"
 #include "sset.h"
 #include "svec.h"
-#include "vswitch-idl.h"
+#include "lib/vswitch-idl.h"
 #include "table.h"
 #include "timeval.h"
 #include "util.h"
@@ -138,9 +138,8 @@ static void parse_command(int argc, char *argv[], struct vsctl_command *);
 static const struct vsctl_command_syntax *find_command(const char *name);
 static void run_prerequisites(struct vsctl_command[], size_t n_commands,
                               struct ovsdb_idl *);
-static enum ovsdb_idl_txn_status do_vsctl(const char *args,
-                                          struct vsctl_command *, size_t n,
-                                          struct ovsdb_idl *);
+static void do_vsctl(const char *args, struct vsctl_command *, size_t n,
+                     struct ovsdb_idl *);
 
 static const struct vsctl_table_class *get_table(const char *table_name);
 static void set_column(const struct vsctl_table_class *,
@@ -156,9 +155,9 @@ int
 main(int argc, char *argv[])
 {
     extern struct vlog_module VLM_reconnect;
-    enum ovsdb_idl_txn_status status;
     struct ovsdb_idl *idl;
     struct vsctl_command *commands;
+    unsigned int seqno;
     size_t n_commands;
     char *args;
 
@@ -184,14 +183,23 @@ main(int argc, char *argv[])
     idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false);
     run_prerequisites(commands, n_commands, idl);
 
-    /* Now execute the commands. */
-    status = TXN_AGAIN_WAIT;
+    /* Execute the commands.
+     *
+     * 'seqno' is the database sequence number for which we last tried to
+     * execute our transaction.  There's no point in trying to commit more than
+     * once for any given sequence number, because if the transaction fails
+     * it's because the database changed and we need to obtain an up-to-date
+     * view of the database before we try the transaction again. */
+    seqno = ovsdb_idl_get_seqno(idl);
     for (;;) {
-        if (ovsdb_idl_run(idl) || status == TXN_AGAIN_NOW) {
-            status = do_vsctl(args, commands, n_commands, idl);
+        ovsdb_idl_run(idl);
+
+        if (seqno != ovsdb_idl_get_seqno(idl)) {
+            seqno = ovsdb_idl_get_seqno(idl);
+            do_vsctl(args, commands, n_commands, idl);
         }
 
-        if (status != TXN_AGAIN_NOW) {
+        if (seqno == ovsdb_idl_get_seqno(idl)) {
             ovsdb_idl_wait(idl);
             poll_block();
         }
@@ -612,8 +620,13 @@ struct vsctl_bridge {
     struct ovsrec_controller **ctrl;
     char *fail_mode;
     size_t n_ctrl;
-    struct vsctl_bridge *parent;
-    int vlan;
+
+    /* VLAN ("fake") bridge support.
+     *
+     * Use 'parent != NULL' to detect a fake bridge, because 'vlan' can be 0
+     * in either case. */
+    struct vsctl_bridge *parent; /* Real bridge, or NULL. */
+    int vlan;                    /* VLAN VID (0...4095), or 0. */
 };
 
 struct vsctl_port {
@@ -704,7 +717,7 @@ port_is_fake_bridge(const struct ovsrec_port *port_cfg)
 {
     return (port_cfg->fake_bridge
             && port_cfg->tag
-            && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
+            && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095);
 }
 
 static struct vsctl_bridge *
@@ -841,7 +854,7 @@ get_info(struct vsctl_context *ctx, struct vsctl_info *info)
             port = xmalloc(sizeof *port);
             port->port_cfg = port_cfg;
             if (port_cfg->tag
-                && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
+                && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095) {
                 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
                 if (!port->bridge) {
                     port->bridge = br;
@@ -1329,8 +1342,8 @@ cmd_add_br(struct vsctl_context *ctx)
     } else if (ctx->argc == 4) {
         parent_name = ctx->argv[2];
         vlan = atoi(ctx->argv[3]);
-        if (vlan < 1 || vlan > 4095) {
-            vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
+        if (vlan < 0 || vlan > 4095) {
+            vsctl_fatal("%s: vlan must be between 0 and 4095", ctx->argv[0]);
         }
     } else {
         vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
@@ -1365,6 +1378,7 @@ cmd_add_br(struct vsctl_context *ctx)
                                 br_name, parent_name, vlan, br_name, br->vlan);
                 }
             }
+            free_info(&info);
             return;
         }
     }
@@ -1397,7 +1411,7 @@ cmd_add_br(struct vsctl_context *ctx)
         int64_t tag = vlan;
 
         parent = find_bridge(&info, parent_name, false);
-        if (parent && parent->vlan) {
+        if (parent && parent->parent) {
             vsctl_fatal("cannot create bridge with fake bridge as parent");
         }
         if (!parent) {
@@ -1725,6 +1739,7 @@ add_port(struct vsctl_context *ctx,
 
             svec_destroy(&want_names);
             svec_destroy(&have_names);
+            free_info(&info);
 
             return;
         }
@@ -1750,7 +1765,7 @@ add_port(struct vsctl_context *ctx,
     ovsrec_port_set_bond_fake_iface(port, fake_iface);
     free(ifaces);
 
-    if (bridge->vlan) {
+    if (bridge->parent) {
         int64_t tag = bridge->vlan;
         ovsrec_port_set_tag(port, &tag, 1);
     }
@@ -3535,6 +3550,7 @@ is_condition_satisfied(const struct vsctl_table_class *table,
         }
 
         ovsdb_atom_destroy(&want_key, column->type.key.type);
+        ovsdb_datum_destroy(&b, &type);
     } else {
         struct ovsdb_datum want_datum;
 
@@ -3589,20 +3605,6 @@ cmd_wait_until(struct vsctl_context *ctx)
     }
 }
 \f
-static struct json *
-where_uuid_equals(const struct uuid *uuid)
-{
-    return
-        json_array_create_1(
-            json_array_create_3(
-                json_string_create("_uuid"),
-                json_string_create("=="),
-                json_array_create_2(
-                    json_string_create("uuid"),
-                    json_string_create_nocopy(
-                        xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
-}
-
 static void
 vsctl_context_init(struct vsctl_context *ctx, struct vsctl_command *command,
                    struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
@@ -3658,7 +3660,7 @@ run_prerequisites(struct vsctl_command *commands, size_t n_commands,
     }
 }
 
-static enum ovsdb_idl_txn_status
+static void
 do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
          struct ovsdb_idl *idl)
 {
@@ -3685,9 +3687,8 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     }
 
     if (wait_for_reload) {
-        struct json *where = where_uuid_equals(&ovs->header_.uuid);
-        ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg", where);
-        json_destroy(where);
+        ovsdb_idl_txn_increment(txn, &ovs->header_,
+                                &ovsrec_open_vswitch_col_next_cfg);
     }
 
     symtab = ovsdb_symbol_table_create();
@@ -3705,7 +3706,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         vsctl_context_done(&ctx, c);
 
         if (ctx.try_again) {
-            status = TXN_AGAIN_WAIT;
+            status = TXN_TRY_AGAIN;
             goto try_again;
         }
     }
@@ -3762,8 +3763,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     case TXN_SUCCESS:
         break;
 
-    case TXN_AGAIN_WAIT:
-    case TXN_AGAIN_NOW:
+    case TXN_TRY_AGAIN:
         goto try_again;
 
     case TXN_ERROR:
@@ -3847,8 +3847,6 @@ try_again:
         free(c->table);
     }
     free(error);
-
-    return status;
 }
 
 static const struct vsctl_command_syntax all_commands[] = {