summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRyan Moats <rmoats@us.ibm.com>2016-08-15 18:47:29 +0000
committerBen Pfaff <blp@ovn.org>2016-08-15 17:26:15 -0700
commit1f4a7252d9e7ee102b76325daca2b7007e5da7f7 (patch)
treeedcbbe2a8bc31820cdc030a852598ef935ee0199 /lib
parent239fa5bbe6e54abcec9b58b137a566d06edaba49 (diff)
downloadopenvswitch-1f4a7252d9e7ee102b76325daca2b7007e5da7f7.tar.gz
Add read-only option to ovs-dpctl and ovs-ofctl commands.
ovs-dpctl and ovs-ofctl lack a read-only option to prevent running of commands that perform read-write operations. Add it and the necessary scaffolding to each. Signed-off-by: Ryan Moats <rmoats@us.ibm.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/command-line.c48
-rw-r--r--lib/command-line.h6
-rw-r--r--lib/db-ctl-base.h2
-rw-r--r--lib/dpctl.c47
-rw-r--r--lib/dpctl.h3
5 files changed, 70 insertions, 36 deletions
diff --git a/lib/command-line.c b/lib/command-line.c
index bda5ed6c0..81283314d 100644
--- a/lib/command-line.c
+++ b/lib/command-line.c
@@ -87,20 +87,10 @@ ovs_cmdl_print_options(const struct option options[])
ds_destroy(&ds);
}
-/* Runs the command designated by argv[0] within the command table specified by
- * 'commands', which must be terminated by a command whose 'name' member is a
- * null pointer.
- *
- * Command-line options should be stripped off, so that a typical invocation
- * looks like:
- * struct ovs_cmdl_context ctx = {
- * .argc = argc - optind,
- * .argv = argv + optind,
- * };
- * ovs_cmdl_run_command(&ctx, my_commands);
- * */
-void
-ovs_cmdl_run_command(struct ovs_cmdl_context *ctx, const struct ovs_cmdl_command commands[])
+static void
+ovs_cmdl_run_command__(struct ovs_cmdl_context *ctx,
+ const struct ovs_cmdl_command commands[],
+ bool read_only)
{
const struct ovs_cmdl_command *p;
@@ -118,6 +108,10 @@ ovs_cmdl_run_command(struct ovs_cmdl_context *ctx, const struct ovs_cmdl_command
VLOG_FATAL("'%s' command takes at most %d arguments",
p->name, p->max_args);
} else {
+ if (p->mode == OVS_RW && read_only) {
+ VLOG_FATAL("'%s' command does not work in read only mode",
+ p->name);
+ }
p->handler(ctx);
if (ferror(stdout)) {
VLOG_FATAL("write to stdout failed");
@@ -132,6 +126,32 @@ ovs_cmdl_run_command(struct ovs_cmdl_context *ctx, const struct ovs_cmdl_command
VLOG_FATAL("unknown command '%s'; use --help for help", ctx->argv[0]);
}
+
+/* Runs the command designated by argv[0] within the command table specified by
+ * 'commands', which must be terminated by a command whose 'name' member is a
+ * null pointer.
+ *
+ * Command-line options should be stripped off, so that a typical invocation
+ * looks like:
+ * struct ovs_cmdl_context ctx = {
+ * .argc = argc - optind,
+ * .argv = argv + optind,
+ * };
+ * ovs_cmdl_run_command(&ctx, my_commands);
+ * */
+void
+ovs_cmdl_run_command(struct ovs_cmdl_context *ctx,
+ const struct ovs_cmdl_command commands[])
+{
+ ovs_cmdl_run_command__(ctx, commands, false);
+}
+
+void
+ovs_cmdl_run_command_read_only(struct ovs_cmdl_context *ctx,
+ const struct ovs_cmdl_command commands[])
+{
+ ovs_cmdl_run_command__(ctx, commands, true);
+}
/* Process title. */
diff --git a/lib/command-line.h b/lib/command-line.h
index e9e3b7bec..00ace949b 100644
--- a/lib/command-line.h
+++ b/lib/command-line.h
@@ -41,12 +41,16 @@ struct ovs_cmdl_command {
int min_args;
int max_args;
ovs_cmdl_handler handler;
+ enum { OVS_RO, OVS_RW } mode; /* Does this command modify things? */
};
char *ovs_cmdl_long_options_to_short_options(const struct option *options);
void ovs_cmdl_print_options(const struct option *options);
void ovs_cmdl_print_commands(const struct ovs_cmdl_command *commands);
-void ovs_cmdl_run_command(struct ovs_cmdl_context *, const struct ovs_cmdl_command[]);
+void ovs_cmdl_run_command(struct ovs_cmdl_context *,
+ const struct ovs_cmdl_command[]);
+void ovs_cmdl_run_command_read_only(struct ovs_cmdl_context *,
+ const struct ovs_cmdl_command[]);
void ovs_cmdl_proctitle_init(int argc, char **argv);
#if defined(__FreeBSD__) || defined(__NetBSD__)
diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h
index 0f4658e38..e5a354de7 100644
--- a/lib/db-ctl-base.h
+++ b/lib/db-ctl-base.h
@@ -120,7 +120,7 @@ struct ctl_command_syntax {
* empty string if the command does not support any options. */
const char *options;
- enum { RO, RW } mode; /* Does this command modify the database? */
+ enum { RO, RW } mode; /* Does this command modify the database? */
};
/* A command extracted from command-line input plus the structs for
diff --git a/lib/dpctl.c b/lib/dpctl.c
index b470ab0dc..28f2f834d 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -59,6 +59,7 @@ struct dpctl_command {
int min_args;
int max_args;
dpctl_command_handler *handler;
+ enum { DP_RO, DP_RW} mode;
};
static const struct dpctl_command *get_all_dpctl_commands(void);
static void dpctl_print(struct dpctl_params *dpctl_p, const char *fmt, ...)
@@ -1615,29 +1616,29 @@ out:
}
static const struct dpctl_command all_commands[] = {
- { "add-dp", "add-dp dp [iface...]", 1, INT_MAX, dpctl_add_dp },
- { "del-dp", "del-dp dp", 1, 1, dpctl_del_dp },
- { "add-if", "add-if dp iface...", 2, INT_MAX, dpctl_add_if },
- { "del-if", "del-if dp iface...", 2, INT_MAX, dpctl_del_if },
- { "set-if", "set-if dp iface...", 2, INT_MAX, dpctl_set_if },
- { "dump-dps", "", 0, 0, dpctl_dump_dps },
- { "show", "[dp...]", 0, INT_MAX, dpctl_show },
- { "dump-flows", "[dp]", 0, 2, dpctl_dump_flows },
- { "add-flow", "add-flow [dp] flow actions", 2, 3, dpctl_add_flow },
- { "mod-flow", "mod-flow [dp] flow actions", 2, 3, dpctl_mod_flow },
- { "get-flow", "get-flow [dp] ufid", 1, 2, dpctl_get_flow },
- { "del-flow", "del-flow [dp] flow", 1, 2, dpctl_del_flow },
- { "del-flows", "[dp]", 0, 1, dpctl_del_flows },
- { "dump-conntrack", "[dp] [zone=N]", 0, 2, dpctl_dump_conntrack },
- { "flush-conntrack", "[dp] [zone=N]", 0, 2, dpctl_flush_conntrack },
- { "help", "", 0, INT_MAX, dpctl_help },
- { "list-commands", "", 0, INT_MAX, dpctl_list_commands },
+ { "add-dp", "add-dp dp [iface...]", 1, INT_MAX, dpctl_add_dp, DP_RW },
+ { "del-dp", "del-dp dp", 1, 1, dpctl_del_dp, DP_RW },
+ { "add-if", "add-if dp iface...", 2, INT_MAX, dpctl_add_if, DP_RW },
+ { "del-if", "del-if dp iface...", 2, INT_MAX, dpctl_del_if, DP_RW },
+ { "set-if", "set-if dp iface...", 2, INT_MAX, dpctl_set_if, DP_RW },
+ { "dump-dps", "", 0, 0, dpctl_dump_dps, DP_RO },
+ { "show", "[dp...]", 0, INT_MAX, dpctl_show, DP_RO },
+ { "dump-flows", "[dp]", 0, 2, dpctl_dump_flows, DP_RO },
+ { "add-flow", "add-flow [dp] flow actions", 2, 3, dpctl_add_flow, DP_RW },
+ { "mod-flow", "mod-flow [dp] flow actions", 2, 3, dpctl_mod_flow, DP_RW },
+ { "get-flow", "get-flow [dp] ufid", 1, 2, dpctl_get_flow, DP_RO },
+ { "del-flow", "del-flow [dp] flow", 1, 2, dpctl_del_flow, DP_RW },
+ { "del-flows", "[dp]", 0, 1, dpctl_del_flows, DP_RW },
+ { "dump-conntrack", "[dp] [zone=N]", 0, 2, dpctl_dump_conntrack, DP_RO },
+ { "flush-conntrack", "[dp] [zone=N]", 0, 2, dpctl_flush_conntrack, DP_RW },
+ { "help", "", 0, INT_MAX, dpctl_help, DP_RO },
+ { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO },
/* Undocumented commands for testing. */
- { "parse-actions", "actions", 1, INT_MAX, dpctl_parse_actions },
- { "normalize-actions", "actions", 2, INT_MAX, dpctl_normalize_actions },
+ { "parse-actions", "actions", 1, INT_MAX, dpctl_parse_actions, DP_RO },
+ { "normalize-actions", "actions", 2, INT_MAX, dpctl_normalize_actions, DP_RO },
- { NULL, NULL, 0, 0, NULL },
+ { NULL, NULL, 0, 0, NULL, DP_RO },
};
static const struct dpctl_command *get_all_dpctl_commands(void)
@@ -1672,6 +1673,12 @@ dpctl_run_command(int argc, const char *argv[], struct dpctl_params *dpctl_p)
p->name, p->max_args);
return EINVAL;
} else {
+ if (p->mode == DP_RW && dpctl_p->read_only) {
+ dpctl_error(dpctl_p, 0,
+ "'%s' command does not work in read only mode",
+ p->name);
+ return EINVAL;
+ }
return p->handler(argc, argv, dpctl_p);
}
}
diff --git a/lib/dpctl.h b/lib/dpctl.h
index 11a172dd9..4ee083fa7 100644
--- a/lib/dpctl.h
+++ b/lib/dpctl.h
@@ -33,6 +33,9 @@ struct dpctl_params {
/* --may-create: Allow mod-flows command to create a new flow? */
bool may_create;
+ /* --read-only: Do not run R/W commands? */
+ bool read_only;
+
/* -m, --more: Increase output verbosity. */
int verbosity;