lib: simplify flow_extract() API
[sliver-openvswitch.git] / utilities / ovs-vsctl.c
index aed90fd..21ac777 100644 (file)
@@ -31,6 +31,7 @@
 #include "compiler.h"
 #include "dirs.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "hash.h"
 #include "json.h"
 #include "ovsdb-data.h"
@@ -128,7 +129,7 @@ static bool retry;
 static struct table_style table_style = TABLE_STYLE_DEFAULT;
 
 /* All supported commands. */
-static const struct vsctl_command_syntax all_commands[];
+static const struct vsctl_command_syntax *get_all_commands(void);
 
 /* The IDL we're using and the current transaction, if any.
  * This is for use by vsctl_exit() only, to allow it to clean up.
@@ -176,7 +177,7 @@ main(int argc, char *argv[])
     char *args;
 
     set_program_name(argv[0]);
-    signal(SIGPIPE, SIG_IGN);
+    fatal_ignore_sigpipe();
     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
     vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN);
     ovsrec_init();
@@ -302,7 +303,7 @@ parse_options(int argc, char *argv[], struct shash *local_options)
     options = xmemdup(global_long_options, sizeof global_long_options);
     allocated_options = ARRAY_SIZE(global_long_options);
     n_options = n_global_long_options;
-    for (p = all_commands; p->name; p++) {
+    for (p = get_all_commands(); p->name; p++) {
         if (p->options[0]) {
             char *save_ptr = NULL;
             char *name;
@@ -391,6 +392,7 @@ parse_options(int argc, char *argv[], struct shash *local_options)
 
         case 'V':
             ovs_print_version(0, 0);
+            printf("DB Schema %s\n", ovsrec_get_db_version());
             exit(EXIT_SUCCESS);
 
         case 't':
@@ -568,7 +570,7 @@ find_command(const char *name)
     if (shash_is_empty(&commands)) {
         const struct vsctl_command_syntax *p;
 
-        for (p = all_commands; p->name; p++) {
+        for (p = get_all_commands(); p->name; p++) {
             shash_add_assert(&commands, p->name, p);
         }
     }
@@ -1453,6 +1455,7 @@ pre_cmd_emer_reset(struct vsctl_context *ctx)
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_mirrors);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_netflow);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_sflow);
+    ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ipfix);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_flood_vlans);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_other_config);
 
@@ -1477,6 +1480,8 @@ cmd_emer_reset(struct vsctl_context *ctx)
     const struct ovsrec_netflow *nf, *next_nf;
     const struct ovsrec_ssl *ssl, *next_ssl;
     const struct ovsrec_sflow *sflow, *next_sflow;
+    const struct ovsrec_ipfix *ipfix, *next_ipfix;
+    const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
 
     /* Reset the Open_vSwitch table. */
     ovsrec_open_vswitch_set_manager_options(ctx->ovs, NULL, 0);
@@ -1490,6 +1495,7 @@ cmd_emer_reset(struct vsctl_context *ctx)
         ovsrec_bridge_set_mirrors(br, NULL, 0);
         ovsrec_bridge_set_netflow(br, NULL);
         ovsrec_bridge_set_sflow(br, NULL);
+        ovsrec_bridge_set_ipfix(br, NULL);
         ovsrec_bridge_set_flood_vlans(br, NULL, 0);
 
         /* We only want to save the "hwaddr" key from other_config. */
@@ -1539,6 +1545,14 @@ cmd_emer_reset(struct vsctl_context *ctx)
         ovsrec_sflow_delete(sflow);
     }
 
+    OVSREC_IPFIX_FOR_EACH_SAFE (ipfix, next_ipfix, idl) {
+        ovsrec_ipfix_delete(ipfix);
+    }
+
+    OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset, idl) {
+        ovsrec_flow_sample_collector_set_delete(fscset);
+    }
+
     vsctl_context_invalidate_cache(ctx);
 }
 
@@ -1668,6 +1682,7 @@ del_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br)
 {
     struct vsctl_bridge *child, *next_child;
     struct vsctl_port *port, *next_port;
+    const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
 
     HMAP_FOR_EACH_SAFE (child, next_child, children_node, &br->children) {
         del_bridge(ctx, child);
@@ -1677,6 +1692,13 @@ del_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br)
         del_port(ctx, port);
     }
 
+    OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset,
+                                                    ctx->idl) {
+        if (fscset->bridge == br->br_cfg) {
+            ovsrec_flow_sample_collector_set_delete(fscset);
+        }
+    }
+
     del_cached_bridge(ctx, br);
 }
 
@@ -1996,13 +2018,20 @@ cmd_del_port(struct vsctl_context *ctx)
 {
     bool must_exist = !shash_find(&ctx->options, "--if-exists");
     bool with_iface = shash_find(&ctx->options, "--with-iface") != NULL;
+    const char *target = ctx->argv[ctx->argc - 1];
     struct vsctl_port *port;
 
     vsctl_context_populate_cache(ctx);
-    if (!with_iface) {
-        port = find_port(ctx, ctx->argv[ctx->argc - 1], must_exist);
+    if (find_bridge(ctx, target, false)) {
+        if (must_exist) {
+            vsctl_fatal("cannot delete port %s because it is the local port "
+                        "for bridge %s (deleting this port requires deleting "
+                        "the entire bridge)", target, target);
+        }
+        port = NULL;
+    } else if (!with_iface) {
+        port = find_port(ctx, target, must_exist);
     } else {
-        const char *target = ctx->argv[ctx->argc - 1];
         struct vsctl_iface *iface;
 
         port = find_port(ctx, target, false);
@@ -2464,7 +2493,8 @@ struct vsctl_table_class {
 static const struct vsctl_table_class tables[] = {
     {&ovsrec_table_bridge,
      {{&ovsrec_table_bridge, &ovsrec_bridge_col_name, NULL},
-      {NULL, NULL, NULL}}},
+      {&ovsrec_table_flow_sample_collector_set, NULL,
+       &ovsrec_flow_sample_collector_set_col_bridge}}},
 
     {&ovsrec_table_controller,
      {{&ovsrec_table_bridge,
@@ -2518,6 +2548,17 @@ static const struct vsctl_table_class tables[] = {
      {{&ovsrec_table_flow_table, &ovsrec_flow_table_col_name, NULL},
       {NULL, NULL, NULL}}},
 
+    {&ovsrec_table_ipfix,
+     {{&ovsrec_table_bridge,
+       &ovsrec_bridge_col_name,
+       &ovsrec_bridge_col_ipfix},
+      {&ovsrec_table_flow_sample_collector_set, NULL,
+       &ovsrec_flow_sample_collector_set_col_ipfix}}},
+
+    {&ovsrec_table_flow_sample_collector_set,
+     {{NULL, NULL, NULL},
+      {NULL, NULL, NULL}}},
+
     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
 };
 
@@ -3313,6 +3354,7 @@ set_column(const struct vsctl_table_class *table,
 
         ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
                           &column->type, false);
+        ovsdb_idl_txn_verify(row, column);
         ovsdb_idl_txn_write(row, column, &datum);
     } else {
         struct ovsdb_datum datum;
@@ -3591,7 +3633,7 @@ post_create(struct vsctl_context *ctx)
     struct uuid dummy;
 
     if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
     real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
     if (real) {
@@ -3709,7 +3751,7 @@ evaluate_relop(const struct ovsdb_datum *a, const struct ovsdb_datum *b,
         return ovsdb_datum_includes_all(b, a, type);
 
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -4019,7 +4061,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     switch (status) {
     case TXN_UNCOMMITTED:
     case TXN_INCOMPLETE:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
 
     case TXN_ABORTED:
         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
@@ -4040,7 +4082,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         vsctl_fatal("database not locked");
 
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
     free(error);
 
@@ -4083,6 +4125,11 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     free(commands);
 
     if (wait_for_reload && status != TXN_UNCHANGED) {
+        /* Even, if --retry flag was not specified, ovs-vsctl still
+         * has to retry to establish OVSDB connection, if wait_for_reload
+         * was set.  Otherwise, ovs-vsctl would end up waiting forever
+         * until cur_cfg would be updated. */
+        ovsdb_idl_enable_reconnect(idl);
         for (;;) {
             ovsdb_idl_run(idl);
             OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
@@ -4189,3 +4236,7 @@ static const struct vsctl_command_syntax all_commands[] = {
     {NULL, 0, 0, NULL, NULL, NULL, NULL, RO},
 };
 
+static const struct vsctl_command_syntax *get_all_commands(void)
+{
+    return all_commands;
+}