diff options
author | Ryan Moats <rmoats@us.ibm.com> | 2016-08-15 18:47:29 +0000 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-08-15 17:26:15 -0700 |
commit | 1f4a7252d9e7ee102b76325daca2b7007e5da7f7 (patch) | |
tree | edcbbe2a8bc31820cdc030a852598ef935ee0199 /lib | |
parent | 239fa5bbe6e54abcec9b58b137a566d06edaba49 (diff) | |
download | openvswitch-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.c | 48 | ||||
-rw-r--r-- | lib/command-line.h | 6 | ||||
-rw-r--r-- | lib/db-ctl-base.h | 2 | ||||
-rw-r--r-- | lib/dpctl.c | 47 | ||||
-rw-r--r-- | lib/dpctl.h | 3 |
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; |