#include <config.h>
#include <getopt.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#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"
%s: OVN northbound DB management utility\n\
usage: %s [OPTIONS] COMMAND [ARG...]\n\
\n\
-Logical Switch Commands:\n\
- lswitch-add [name] Create a logical switch\n\
- lswitch-del <lswitch> Delete a logical switch\n\
- lswitch-list List configured logical switches\n\
- lswitch-set-external-id <lswitch> <key> [value]\n\
- Set or delete an external:id on a logical switch\n\
- lswitch-get-external-id <lswitch> [key]\n\
- List one or all external:ids set on a switch\n\
+General commands:\n\
+ show print overview of database contents\n\
\n\
-Logical Port Commands:\n\
- lport-add <name> <lswitch> Create a logical port on a logical switch\n\
- lport-del <lport> Delete a logical port (by name or UUID)\n\
- lport-list <lswitch> List ports on a logical switch\n\
- lport-set-external-id <lport> <key> [value]\n\
- Set or delete an external:id on a logical port\n\
- lport-get-external-id <lport> [key]\n\
- List one or all external:ids set on a port\n\
- lport-set-macs <lport> [MAC] [MAC] [...]\n\
- Set MAC addresses for the logical port. Specify\n\
- more than one using additional arguments.\n\
- lport-get-macs <lport> Get a list of MAC addresses on the port.\n\
- lport-get-up <lport> Get state of the port ('up' or 'down').\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\
+ lswitch-list print the names of all logical switches\n\
+ lswitch-set-external-id LSWITCH KEY [VALUE]\n\
+ set or delete an external-id on LSWITCH\n\
+ lswitch-get-external-id LSWITCH [KEY]\n\
+ list one or all external-ids on LSWITCH\n\
+\n\
+Logical port commands:\n\
+ lport-add LSWITCH LPORT add logical port LPORT on LSWITCH\n\
+ lport-add LSWITCH LPORT PARENT TAG\n\
+ add logical port LPORT on LSWITCH with PARENT\n\
+ on TAG\n\
+ lport-del LPORT delete LPORT from its attached switch\n\
+ lport-list LSWITCH print the names of all logical ports on LSWITCH\n\
+ lport-get-parent LPORT get the parent of LPORT if set\n\
+ lport-get-tag LPORT get the LPORT's tag if set\n\
+ lport-set-external-id LPORT KEY [VALUE]\n\
+ set or delete an external-id on LPORT\n\
+ lport-get-external-id LPORT [KEY]\n\
+ list one or all external-ids on LPORT\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\
\n\
Options:\n\
--db=DATABASE connect to DATABASE\n\
return lswitch;
}
+static void
+print_lswitch(const struct nbctl_context *nb_ctx,
+ const struct nbrec_logical_switch *lswitch)
+{
+ const struct nbrec_logical_port *lport;
+
+ printf(" lswitch "UUID_FMT" (%s)\n",
+ UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
+
+ NBREC_LOGICAL_PORT_FOR_EACH(lport, nb_ctx->idl) {
+ int i;
+
+ if (lport->lswitch == lswitch) {
+ 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 (i=0; i < lport->n_macs; i++) {
+ printf(" %s", lport->macs[i]);
+ }
+ 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(nb_ctx, lswitch);
+ }
+ } else {
+ NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, nb_ctx->idl) {
+ print_lswitch(nb_ctx, lswitch);
+ }
+ }
+}
+
static void
do_lswitch_add(struct ovs_cmdl_context *ctx)
{
/* List one external ID */
value = smap_get(&lswitch->external_ids, key);
- if (value && *value) {
+ if (value) {
printf("%s\n", value);
- } else {
- printf("external-id '%s' is not set.\n", key);
}
} else {
struct smap_node *node;
struct nbctl_context *nb_ctx = ctx->pvt;
struct nbrec_logical_port *lport;
const struct nbrec_logical_switch *lswitch;
+ int64_t tag;
- lswitch = lswitch_by_name_or_uuid(nb_ctx, ctx->argv[2]);
+ lswitch = lswitch_by_name_or_uuid(nb_ctx, ctx->argv[1]);
if (!lswitch) {
return;
}
+ if (ctx->argc != 3 && ctx->argc != 5) {
+ /* If a parent_name is specififed, a tag must be specified as well. */
+ VLOG_WARN("Invalid arguments to lport-add.");
+ return;
+ }
+
+ if (ctx->argc == 5) {
+ /* Validate tag. */
+ if (!ovs_scan(ctx->argv[4], "%"SCNd64, &tag) || tag < 0 || tag > 4095) {
+ VLOG_WARN("Invalid tag '%s'", ctx->argv[4]);
+ return;
+ }
+ }
+
+ /* Finally, create the transaction. */
lport = nbrec_logical_port_insert(nb_ctx->txn);
- nbrec_logical_port_set_name(lport, ctx->argv[1]);
+ 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);
+ }
}
static void
}
}
+static void
+do_lport_get_parent(struct ovs_cmdl_context *ctx)
+{
+ struct nbctl_context *nb_ctx = ctx->pvt;
+ const struct nbrec_logical_port *lport;
+
+ lport = lport_by_name_or_uuid(nb_ctx, ctx->argv[1]);
+ if (!lport) {
+ return;
+ }
+
+ if (lport->parent_name) {
+ printf("%s\n", lport->parent_name);
+ }
+}
+
+static void
+do_lport_get_tag(struct ovs_cmdl_context *ctx)
+{
+ struct nbctl_context *nb_ctx = ctx->pvt;
+ const struct nbrec_logical_port *lport;
+
+ lport = lport_by_name_or_uuid(nb_ctx, ctx->argv[1]);
+ if (!lport) {
+ return;
+ }
+
+ if (lport->n_tag > 0) {
+ printf("%"PRId64"\n", lport->tag[0]);
+ }
+}
+
static void
do_lport_set_external_id(struct ovs_cmdl_context *ctx)
{
/* List one external ID */
value = smap_get(&lport->external_ids, key);
- if (value && *value) {
+ if (value) {
printf("%s\n", value);
- } else {
- printf("external-id '%s' is not set.\n", key);
}
} else {
struct smap_node *node;
}
}
+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)
{
}
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]",
+ .usage = "[LSWITCH]",
.min_args = 0,
.max_args = 1,
.handler = do_lswitch_add,
},
{
.name = "lswitch-del",
- .usage = "<lswitch>",
+ .usage = "LSWITCH",
.min_args = 1,
.max_args = 1,
.handler = do_lswitch_del,
},
{
.name = "lswitch-set-external-id",
- .usage = "<lswitch> <key> [value]",
+ .usage = "LSWITCH KEY [VALUE]",
.min_args = 2,
.max_args = 3,
.handler = do_lswitch_set_external_id,
},
{
.name = "lswitch-get-external-id",
- .usage = "<lswitch> [key]",
+ .usage = "LSWITCH [KEY]",
.min_args = 1,
.max_args = 2,
.handler = do_lswitch_get_external_id,
},
{
.name = "lport-add",
- .usage = "<name> <lswitch>",
+ .usage = "LSWITCH LPORT [PARENT] [TAG]",
.min_args = 2,
- .max_args = 2,
+ .max_args = 4,
.handler = do_lport_add,
},
{
.name = "lport-del",
- .usage = "<lport>",
+ .usage = "LPORT",
.min_args = 1,
.max_args = 1,
.handler = do_lport_del,
},
{
.name = "lport-list",
- .usage = "<lswitch>",
+ .usage = "LSWITCH",
.min_args = 1,
.max_args = 1,
.handler = do_lport_list,
},
+ {
+ .name = "lport-get-parent",
+ .usage = "LPORT",
+ .min_args = 1,
+ .max_args = 1,
+ .handler = do_lport_get_parent,
+ },
+ {
+ .name = "lport-get-tag",
+ .usage = "LPORT",
+ .min_args = 1,
+ .max_args = 1,
+ .handler = do_lport_get_tag,
+ },
{
.name = "lport-set-external-id",
- .usage = "<lport> <key> [value]",
+ .usage = "LPORT KEY [VALUE]",
.min_args = 2,
.max_args = 3,
.handler = do_lport_set_external_id,
},
{
.name = "lport-get-external-id",
- .usage = "<lport> [key]",
+ .usage = "LPORT [KEY]",
.min_args = 1,
.max_args = 2,
.handler = do_lport_get_external_id,
},
{
.name = "lport-set-macs",
- .usage = "<lport> [MAC] [MAC] [...]",
+ .usage = "LPORT [MAC]...",
.min_args = 1,
/* Accept however many arguments the system will allow. */
.max_args = INT_MAX,
},
{
.name = "lport-get-macs",
- .usage = "<lport>",
+ .usage = "LPORT",
.min_args = 1,
.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>",
+ .usage = "LPORT",
.min_args = 1,
.max_args = 1,
.handler = do_lport_get_up,