X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ovn%2Fovn-nbctl.c;h=0bdb3a38778d7796a5bf908bef8ca9755fc90ef1;hb=62fdd819efe859cb35ae0e4292c0b1cdad330f64;hp=61ec1e9651957e6f075a7742efbeaf012d6cb33c;hpb=2de82d904a873e46943132f98bf8b3e5b2a8dd39;p=cascardo%2Fovs.git diff --git a/ovn/ovn-nbctl.c b/ovn/ovn-nbctl.c index 61ec1e965..0bdb3a387 100644 --- a/ovn/ovn-nbctl.c +++ b/ovn/ovn-nbctl.c @@ -22,7 +22,7 @@ #include "command-line.h" #include "dirs.h" #include "fatal-signal.h" -#include "ovn/ovn-nb-idl.h" +#include "ovn/lib/ovn-nb-idl.h" #include "poll-loop.h" #include "process.h" #include "stream.h" @@ -48,6 +48,10 @@ usage(void) %s: OVN northbound DB management utility\n\ usage: %s [OPTIONS] COMMAND [ARG...]\n\ \n\ +General commands:\n\ + show print overview of database contents\n\ + show LSWITCH print overview of database contents for LSWITCH\n\ +\n\ Logical switch commands:\n\ lswitch-add [LSWITCH] create a logical switch named LSWITCH\n\ lswitch-del LSWITCH delete LSWITCH and all its ports\n\ @@ -73,7 +77,20 @@ Logical port commands:\n\ lport-set-macs LPORT [MAC]...\n\ set MAC addresses for LPORT.\n\ lport-get-macs LPORT get a list of MAC addresses on LPORT\n\ + lport-set-port-security LPORT [ADDRS]...\n\ + set port security addresses for LPORT.\n\ + lport-get-port-security LPORT get LPORT's port security addresses\n\ lport-get-up LPORT get state of LPORT ('up' or 'down')\n\ + lport-set-enabled LPORT STATE\n\ + set administrative state LPORT\n\ + ('enabled' or 'disabled')\n\ + lport-get-enabled LPORT get administrative state LPORT\n\ + ('enabled' or 'disabled')\n\ + lport-set-type LPORT TYPE Set the type for LPORT\n\ + lport-get-type LPORT Get the type for LPORT\n\ + lport-set-options LPORT KEY=VALUE [KEY=VALUE]...\n\ + Set options related to the type of LPORT\n\ + lport-get-options LPORT Get the type specific options for LPORT\n\ \n\ Options:\n\ --db=DATABASE connect to DATABASE\n\ @@ -126,6 +143,48 @@ lswitch_by_name_or_uuid(struct nbctl_context *nb_ctx, const char *id) return lswitch; } +static void +print_lswitch(const struct nbrec_logical_switch *lswitch) +{ + printf(" lswitch "UUID_FMT" (%s)\n", + UUID_ARGS(&lswitch->header_.uuid), lswitch->name); + + for (size_t i = 0; i < lswitch->n_ports; i++) { + const struct nbrec_logical_port *lport = lswitch->ports[i]; + + printf(" lport %s\n", lport->name); + if (lport->parent_name && lport->n_tag) { + printf(" parent: %s, tag:%"PRIu64"\n", + lport->parent_name, lport->tag[0]); + } + if (lport->n_macs) { + printf(" macs:"); + for (size_t j = 0; j < lport->n_macs; j++) { + printf(" %s", lport->macs[j]); + } + printf("\n"); + } + } +} + +static void +do_show(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const struct nbrec_logical_switch *lswitch; + + if (ctx->argc == 2) { + lswitch = lswitch_by_name_or_uuid(nb_ctx, ctx->argv[1]); + if (lswitch) { + print_lswitch(lswitch); + } + } else { + NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, nb_ctx->idl) { + print_lswitch(lswitch); + } + } +} + static void do_lswitch_add(struct ovs_cmdl_context *ctx) { @@ -264,7 +323,7 @@ do_lport_add(struct ovs_cmdl_context *ctx) } if (ctx->argc != 3 && ctx->argc != 5) { - /* If a parent_name is specififed, a tag must be specified as well. */ + /* If a parent_name is specified, a tag must be specified as well. */ VLOG_WARN("Invalid arguments to lport-add."); return; } @@ -277,14 +336,44 @@ do_lport_add(struct ovs_cmdl_context *ctx) } } - /* Finally, create the transaction. */ + /* Create the logical port. */ lport = nbrec_logical_port_insert(nb_ctx->txn); nbrec_logical_port_set_name(lport, ctx->argv[2]); - nbrec_logical_port_set_lswitch(lport, lswitch); if (ctx->argc == 5) { nbrec_logical_port_set_parent_name(lport, ctx->argv[3]); nbrec_logical_port_set_tag(lport, &tag, 1); } + + /* Insert the logical port into the logical switch. */ + nbrec_logical_switch_verify_ports(lswitch); + struct nbrec_logical_port **new_ports = xmalloc(sizeof *new_ports * + (lswitch->n_ports + 1)); + memcpy(new_ports, lswitch->ports, sizeof *new_ports * lswitch->n_ports); + new_ports[lswitch->n_ports] = lport; + nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports + 1); + free(new_ports); +} + +/* Removes lport 'lswitch->ports[idx]'. */ +static void +remove_lport(const struct nbrec_logical_switch *lswitch, size_t idx) +{ + const struct nbrec_logical_port *lport = lswitch->ports[idx]; + + /* First remove 'lport' from the array of ports. This is what will + * actually cause the logical port to be deleted when the transaction is + * sent to the database server (due to garbage collection). */ + struct nbrec_logical_port **new_ports + = xmemdup(lswitch->ports, sizeof *new_ports * lswitch->n_ports); + new_ports[idx] = new_ports[lswitch->n_ports - 1]; + nbrec_logical_switch_verify_ports(lswitch); + nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports - 1); + free(new_ports); + + /* Delete 'lport' from the IDL. This won't have a real effect on the + * database server (the IDL will suppress it in fact) but it means that it + * won't show up when we iterate with NBREC_LOGICAL_PORT_FOR_EACH later. */ + nbrec_logical_port_delete(lport); } static void @@ -298,44 +387,35 @@ do_lport_del(struct ovs_cmdl_context *ctx) return; } - nbrec_logical_port_delete(lport); -} - -static bool -is_lswitch(const struct nbrec_logical_switch *lswitch, - struct uuid *lswitch_uuid, const char *name) -{ - if (lswitch_uuid) { - return uuid_equals(lswitch_uuid, &lswitch->header_.uuid); - } else { - return !strcmp(lswitch->name, name); + /* Find the switch that contains 'lport', then delete it. */ + const struct nbrec_logical_switch *lswitch; + NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, nb_ctx->idl) { + for (size_t i = 0; i < lswitch->n_ports; i++) { + if (lswitch->ports[i] == lport) { + remove_lport(lswitch, i); + return; + } + } } -} + VLOG_WARN("logical port %s is not part of any logical switch", + ctx->argv[1]); +} static void do_lport_list(struct ovs_cmdl_context *ctx) { struct nbctl_context *nb_ctx = ctx->pvt; const char *id = ctx->argv[1]; - const struct nbrec_logical_port *lport; - bool is_uuid = false; - struct uuid lswitch_uuid; + const struct nbrec_logical_switch *lswitch; - if (uuid_from_string(&lswitch_uuid, id)) { - is_uuid = true; + lswitch = lswitch_by_name_or_uuid(nb_ctx, id); + if (!lswitch) { + return; } - NBREC_LOGICAL_PORT_FOR_EACH(lport, nb_ctx->idl) { - bool match; - if (is_uuid) { - match = is_lswitch(lport->lswitch, &lswitch_uuid, NULL); - } else { - match = is_lswitch(lport->lswitch, NULL, id); - } - if (!match) { - continue; - } + for (size_t i = 0; i < lswitch->n_ports; i++) { + const struct nbrec_logical_port *lport = lswitch->ports[i]; printf(UUID_FMT " (%s)\n", UUID_ARGS(&lport->header_.uuid), lport->name); } @@ -464,6 +544,40 @@ do_lport_get_macs(struct ovs_cmdl_context *ctx) } } +static void +do_lport_set_port_security(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + nbrec_logical_port_set_port_security(lport, + (const char **) ctx->argv + 2, ctx->argc - 2); +} + +static void +do_lport_get_port_security(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + size_t i; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + for (i = 0; i < lport->n_port_security; i++) { + printf("%s\n", lport->port_security[i]); + } +} + static void do_lport_get_up(struct ovs_cmdl_context *ctx) { @@ -478,6 +592,124 @@ do_lport_get_up(struct ovs_cmdl_context *ctx) printf("%s\n", (lport->up && *lport->up) ? "up" : "down"); } + +static void +do_lport_set_enabled(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const char *state = ctx->argv[2]; + const struct nbrec_logical_port *lport; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + if (!strcasecmp(state, "enabled")) { + bool enabled = true; + nbrec_logical_port_set_enabled(lport, &enabled, 1); + } else if (!strcasecmp(state, "disabled")) { + bool enabled = false; + nbrec_logical_port_set_enabled(lport, &enabled, 1); + } else { + VLOG_ERR("Invalid state '%s' provided to lport-set-enabled", state); + } +} + +static void +do_lport_get_enabled(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + printf("%s\n", + (!lport->enabled || *lport->enabled) ? "enabled" : "disabled"); +} + +static void +do_lport_set_type(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const char *type = ctx->argv[2]; + const struct nbrec_logical_port *lport; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + nbrec_logical_port_set_type(lport, type); +} + +static void +do_lport_get_type(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + printf("%s\n", lport->type); +} + +static void +do_lport_set_options(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + size_t i; + struct smap options = SMAP_INITIALIZER(&options); + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + for (i = 2; i < ctx->argc; i++) { + char *key, *value; + value = xstrdup(ctx->argv[i]); + key = strsep(&value, "="); + if (value) { + smap_add(&options, key, value); + } + free(key); + } + + nbrec_logical_port_set_options(lport, &options); + + smap_destroy(&options); +} + +static void +do_lport_get_options(struct ovs_cmdl_context *ctx) +{ + struct nbctl_context *nb_ctx = ctx->pvt; + const char *id = ctx->argv[1]; + const struct nbrec_logical_port *lport; + struct smap_node *node; + + lport = lport_by_name_or_uuid(nb_ctx, id); + if (!lport) { + return; + } + + SMAP_FOR_EACH(node, &lport->options) { + printf("%s=%s\n", node->key, node->value); + } +} static void parse_options(int argc, char *argv[]) @@ -537,6 +769,13 @@ parse_options(int argc, char *argv[]) } static const struct ovs_cmdl_command all_commands[] = { + { + .name = "show", + .usage = "[LSWITCH]", + .min_args = 0, + .max_args = 1, + .handler = do_show, + }, { .name = "lswitch-add", .usage = "[LSWITCH]", @@ -636,6 +875,21 @@ static const struct ovs_cmdl_command all_commands[] = { .max_args = 1, .handler = do_lport_get_macs, }, + { + .name = "lport-set-port-security", + .usage = "LPORT [ADDRS]...", + .min_args = 0, + /* Accept however many arguments the system will allow. */ + .max_args = INT_MAX, + .handler = do_lport_set_port_security, + }, + { + .name = "lport-get-port-security", + .usage = "LPORT", + .min_args = 1, + .max_args = 1, + .handler = do_lport_get_port_security, + }, { .name = "lport-get-up", .usage = "LPORT", @@ -643,6 +897,48 @@ static const struct ovs_cmdl_command all_commands[] = { .max_args = 1, .handler = do_lport_get_up, }, + { + .name = "lport-set-enabled", + .usage = "LPORT STATE", + .min_args = 2, + .max_args = 2, + .handler = do_lport_set_enabled, + }, + { + .name = "lport-get-enabled", + .usage = "LPORT", + .min_args = 1, + .max_args = 1, + .handler = do_lport_get_enabled, + }, + { + .name = "lport-set-type", + .usage = "LPORT TYPE", + .min_args = 2, + .max_args = 2, + .handler = do_lport_set_type, + }, + { + .name = "lport-get-type", + .usage = "LPORT", + .min_args = 1, + .max_args = 1, + .handler = do_lport_get_type, + }, + { + .name = "lport-set-options", + .usage = "LPORT KEY=VALUE [KEY=VALUE]...", + .min_args = 1, + .max_args = INT_MAX, + .handler = do_lport_set_options + }, + { + .name = "lport-get-options", + .usage = "LPORT", + .min_args = 1, + .max_args = 1, + .handler = do_lport_get_options, + }, { /* sentinel */ @@ -661,7 +957,10 @@ default_db(void) { static char *def; if (!def) { - def = xasprintf("unix:%s/db.sock", ovs_rundir()); + def = getenv("OVN_NB_DB"); + if (!def) { + def = xasprintf("unix:%s/db.sock", ovs_rundir()); + } } return def; }