struct ovsdb_idl *);
static bool do_nbctl(const char *args, struct ctl_command *, size_t n,
struct ovsdb_idl *);
+static const struct nbrec_dhcp_options *dhcp_options_get(
+ struct ctl_context *ctx, const char *id, bool must_exist);
int
main(int argc, char *argv[])
lsp-set-options PORT KEY=VALUE [KEY=VALUE]...\n\
set options related to the type of PORT\n\
lsp-get-options PORT get the type specific options for PORT\n\
+ lsp-set-dhcpv4-options PORT [DHCP_OPTIONS_UUID]\n\
+ set dhcpv4 options for PORT\n\
+ lsp-get-dhcpv4-options PORT get the dhcpv4 options for PORT\n\
\n\
Logical router commands:\n\
lr-add [ROUTER] create a logical router named ROUTER\n\
remove routes from ROUTER\n\
lr-route-list ROUTER print routes for ROUTER\n\
\n\
+\n\
+DHCP Options commands:\n\
+ dhcp-options-create CIDR [EXTERNAL_IDS]\n\
+ create a DHCP options row with CIDR\n\
+ dhcp-options-del DHCP_OPTIONS_UUID\n\
+ delete DHCP_OPTIONS_UUID\n\
+ dhcp-options-list \n\
+ lists the DHCP_Options rows\n\
+ dhcp-options-set-options DHCP_OPTIONS_UUID KEY=VALUE [KEY=VALUE]...\n\
+ set DHCP options to the DHCP_OPTIONS_UUID\n\
+ dhcp-options-get-options DHCO_OPTIONS_UUID \n\
+ displays the DHCP options of th DHCP_OPTIONS_UUID\n\
+\n\
%s\
\n\
Options:\n\
}
}
+static void
+nbctl_lsp_set_dhcpv4_options(struct ctl_context *ctx)
+{
+ const char *id = ctx->argv[1];
+ const struct nbrec_logical_switch_port *lsp;
+
+ lsp = lsp_by_name_or_uuid(ctx, id, true);
+ const struct nbrec_dhcp_options *dhcp_opt = NULL;
+ if (ctx->argc == 3 ) {
+ dhcp_opt = dhcp_options_get(ctx, ctx->argv[2], true);
+ }
+
+ if (dhcp_opt) {
+ ovs_be32 ip;
+ unsigned int plen;
+ char *error = ip_parse_cidr(dhcp_opt->cidr, &ip, &plen);
+ if (error){
+ free(error);
+ ctl_fatal("DHCP options cidr '%s' is not IPv4", dhcp_opt->cidr);
+ return;
+ }
+ }
+ nbrec_logical_switch_port_set_dhcpv4_options(lsp, dhcp_opt);
+}
+
+static void
+nbctl_lsp_get_dhcpv4_options(struct ctl_context *ctx)
+{
+ const char *id = ctx->argv[1];
+ const struct nbrec_logical_switch_port *lsp;
+
+ lsp = lsp_by_name_or_uuid(ctx, id, true);
+ if (lsp->dhcpv4_options) {
+ ds_put_format(&ctx->output, UUID_FMT " (%s)\n",
+ UUID_ARGS(&lsp->dhcpv4_options->header_.uuid),
+ lsp->dhcpv4_options->cidr);
+ }
+}
+
enum {
DIR_FROM_LPORT,
DIR_TO_LPORT
free(nodes);
}
+static const struct nbrec_dhcp_options *
+dhcp_options_get(struct ctl_context *ctx, const char *id, bool must_exist)
+{
+ struct uuid dhcp_opts_uuid;
+ const struct nbrec_dhcp_options *dhcp_opts = NULL;
+ if (uuid_from_string(&dhcp_opts_uuid, id)) {
+ dhcp_opts = nbrec_dhcp_options_get_for_uuid(ctx->idl, &dhcp_opts_uuid);
+ }
+
+ if (!dhcp_opts && must_exist) {
+ ctl_fatal("%s: dhcp options UUID not found", id);
+ }
+ return dhcp_opts;
+}
+
+static void
+nbctl_dhcp_options_create(struct ctl_context *ctx)
+{
+ /* Validate the cidr */
+ ovs_be32 ip;
+ unsigned int plen;
+ char *error = ip_parse_cidr(ctx->argv[1], &ip, &plen);
+ if (error){
+ /* check if its IPv6 cidr */
+ free(error);
+ struct in6_addr ipv6;
+ error = ipv6_parse_cidr(ctx->argv[1], &ipv6, &plen);
+ if (error) {
+ free(error);
+ ctl_fatal("Invalid cidr format '%s'", ctx->argv[1]);
+ return;
+ }
+ }
+
+ struct nbrec_dhcp_options *dhcp_opts = nbrec_dhcp_options_insert(ctx->txn);
+ nbrec_dhcp_options_set_cidr(dhcp_opts, ctx->argv[1]);
+
+ struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
+ for (size_t i = 2; i < ctx->argc; i++) {
+ char *key, *value;
+ value = xstrdup(ctx->argv[i]);
+ key = strsep(&value, "=");
+ if (value) {
+ smap_add(&ext_ids, key, value);
+ }
+ free(key);
+ }
+
+ nbrec_dhcp_options_set_external_ids(dhcp_opts, &ext_ids);
+ smap_destroy(&ext_ids);
+}
+
+static void
+nbctl_dhcp_options_set_options(struct ctl_context *ctx)
+{
+ const struct nbrec_dhcp_options *dhcp_opts = dhcp_options_get(
+ ctx, ctx->argv[1], true);
+
+ struct smap dhcp_options = SMAP_INITIALIZER(&dhcp_options);
+ for (size_t i = 2; i < ctx->argc; i++) {
+ char *key, *value;
+ value = xstrdup(ctx->argv[i]);
+ key = strsep(&value, "=");
+ if (value) {
+ smap_add(&dhcp_options, key, value);
+ }
+ free(key);
+ }
+
+ nbrec_dhcp_options_set_options(dhcp_opts, &dhcp_options);
+ smap_destroy(&dhcp_options);
+}
+
+static void
+nbctl_dhcp_options_get_options(struct ctl_context *ctx)
+{
+ const struct nbrec_dhcp_options *dhcp_opts = dhcp_options_get(
+ ctx, ctx->argv[1], true);
+
+ struct smap_node *node;
+ SMAP_FOR_EACH(node, &dhcp_opts->options) {
+ ds_put_format(&ctx->output, "%s=%s\n", node->key, node->value);
+ }
+}
+
+static void
+nbctl_dhcp_options_del(struct ctl_context *ctx)
+{
+ bool must_exist = !shash_find(&ctx->options, "--if-exists");
+ const char *id = ctx->argv[1];
+ const struct nbrec_dhcp_options *dhcp_opts;
+
+ dhcp_opts = dhcp_options_get(ctx, id, must_exist);
+ if (!dhcp_opts) {
+ return;
+ }
+
+ nbrec_dhcp_options_delete(dhcp_opts);
+}
+
+static void
+nbctl_dhcp_options_list(struct ctl_context *ctx)
+{
+ const struct nbrec_dhcp_options *dhcp_opts;
+ struct smap dhcp_options;
+
+ smap_init(&dhcp_options);
+ NBREC_DHCP_OPTIONS_FOR_EACH(dhcp_opts, ctx->idl) {
+ smap_add_format(&dhcp_options, dhcp_opts->cidr, UUID_FMT,
+ UUID_ARGS(&dhcp_opts->header_.uuid));
+ }
+ const struct smap_node **nodes = smap_sort(&dhcp_options);
+ for (size_t i = 0; i < smap_count(&dhcp_options); i++) {
+ const struct smap_node *node = nodes[i];
+ ds_put_format(&ctx->output, "%s\n", node->value);
+ }
+ smap_destroy(&dhcp_options);
+ free(nodes);
+}
+
/* The caller must free the returned string. */
static char *
normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen)
{{&nbrec_table_address_set, &nbrec_address_set_col_name, NULL},
{NULL, NULL, NULL}}},
+ {&nbrec_table_dhcp_options,
+ {{&nbrec_table_dhcp_options, NULL,
+ NULL},
+ {NULL, NULL, NULL}}},
+
{NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
};
\f
nbctl_lsp_set_options, NULL, "", RW },
{ "lsp-get-options", 1, 1, "PORT", NULL, nbctl_lsp_get_options, NULL,
"", RO },
+ { "lsp-set-dhcpv4-options", 1, 2, "PORT [DHCP_OPT_UUID]", NULL,
+ nbctl_lsp_set_dhcpv4_options, NULL, "", RW },
+ { "lsp-get-dhcpv4-options", 1, 1, "PORT", NULL,
+ nbctl_lsp_get_dhcpv4_options, NULL, "", RO },
/* logical router commands. */
{ "lr-add", 0, 1, "[ROUTER]", NULL, nbctl_lr_add, NULL,
{ "lr-route-list", 1, 1, "ROUTER", NULL, nbctl_lr_route_list, NULL,
"", RO },
+ /* DHCP_Options commands */
+ {"dhcp-options-create", 1, INT_MAX, "CIDR [EXTERNAL:IDS]", NULL,
+ nbctl_dhcp_options_create, NULL, "", RW },
+ {"dhcp-options-del", 1, 1, "DHCP_OPT_UUID", NULL,
+ nbctl_dhcp_options_del, NULL, "", RW},
+ {"dhcp-options-list", 0, 0, "", NULL, nbctl_dhcp_options_list, NULL, "", RO},
+ {"dhcp-options-set-options", 1, INT_MAX, "DHCP_OPT_UUID KEY=VALUE [KEY=VALUE]...",
+ NULL, nbctl_dhcp_options_set_options, NULL, "", RW },
+ {"dhcp-options-get-options", 1, 1, "DHCP_OPT_UUID", NULL,
+ nbctl_dhcp_options_get_options, NULL, "", RO },
+
{NULL, 0, 0, NULL, NULL, NULL, NULL, "", RO},
};