summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/db-ctl-base.c58
-rw-r--r--lib/db-ctl-base.h6
-rw-r--r--ovn/utilities/ovn-nbctl.c11
-rw-r--r--ovn/utilities/ovn-sbctl.c9
-rw-r--r--utilities/ovs-vsctl.c28
-rw-r--r--vtep/vtep-ctl.c11
6 files changed, 79 insertions, 44 deletions
diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c
index c2a0be021..d40b5e6a8 100644
--- a/lib/db-ctl-base.c
+++ b/lib/db-ctl-base.c
@@ -251,15 +251,26 @@ get_row_by_id(struct ctl_context *ctx,
}
const struct ovsdb_idl_row *referrer = NULL;
- ovs_assert(id->name_column->type.value.type == OVSDB_TYPE_VOID);
- enum ovsdb_atomic_type key = id->name_column->type.key.type;
- if (key == OVSDB_TYPE_INTEGER) {
+ /* Figure out the 'key' and 'value' types for the column that we're going
+ * to look at. One of these ('name_type') is the type of the name we're
+ * going to compare against 'record_id'. */
+ enum ovsdb_atomic_type key, value, name_type;
+ if (!id->key) {
+ name_type = key = id->name_column->type.key.type;
+ value = OVSDB_TYPE_VOID;
+ } else {
+ key = OVSDB_TYPE_STRING;
+ name_type = value = id->name_column->type.value.type;
+ }
+
+ /* We only support integer and string names (so far). */
+ if (name_type == OVSDB_TYPE_INTEGER) {
if (!record_id[0] || record_id[strspn(record_id, "0123456789")]) {
return NULL;
}
} else {
- ovs_assert(key == OVSDB_TYPE_STRING);
+ ovs_assert(name_type == OVSDB_TYPE_STRING);
}
const struct ovsdb_idl_class *class = ovsdb_idl_get_class(ctx->idl);
@@ -269,19 +280,34 @@ get_row_by_id(struct ctl_context *ctx,
id_table);
row != NULL;
row = ovsdb_idl_next_row(row)) {
- const struct ovsdb_datum *name = ovsdb_idl_get(
- row, id->name_column, key, OVSDB_TYPE_VOID);
- if (name->n == 1) {
- const union ovsdb_atom *atom = &name->keys[0];
- if (key == OVSDB_TYPE_STRING
- ? !strcmp(atom->string, record_id)
- : atom->integer == strtoll(record_id, NULL, 10)) {
- if (referrer) {
- ctl_fatal("multiple rows in %s match \"%s\"",
- id_table->name, record_id);
- }
- referrer = row;
+ /* Pick out the name column's data. */
+ const struct ovsdb_datum *datum = ovsdb_idl_get(
+ row, id->name_column, key, value);
+
+ /* Extract the name from the column. */
+ const union ovsdb_atom *name;
+ if (!id->key) {
+ name = datum->n == 1 ? &datum->keys[0] : NULL;
+ } else {
+ const union ovsdb_atom key
+ = { .string = CONST_CAST(char *, id->key) };
+ unsigned int i = ovsdb_datum_find_key(datum, &key,
+ OVSDB_TYPE_STRING);
+ name = i == UINT_MAX ? NULL : &datum->values[i];
+ }
+ if (!name) {
+ continue;
+ }
+
+ /* If the name equals 'record_id', take it. */
+ if (name_type == OVSDB_TYPE_STRING
+ ? !strcmp(name->string, record_id)
+ : name->integer == strtoll(record_id, NULL, 10)) {
+ if (referrer) {
+ ctl_fatal("multiple rows in %s match \"%s\"",
+ id_table->name, record_id);
}
+ referrer = row;
}
}
if (!referrer) {
diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h
index e89140982..29fea2bd9 100644
--- a/lib/db-ctl-base.h
+++ b/lib/db-ctl-base.h
@@ -240,7 +240,10 @@ void ctl_context_done(struct ctl_context *, struct ctl_command *);
/* A way to identify a particular row in the database based on a user-provided
* string. If all fields are NULL, the struct is ignored. Otherwise,
* 'name_column' designates a column whose table is searched for rows that
- * match with the user string. If a matching row is found, then:
+ * match with the user string. If 'key' is NULL, then 'name_column' should be
+ * a string or integer-valued column; otherwise it should be a map from a
+ * string to one of those types and the value corresponding to 'key' is what is
+ * matched. If a matching row is found, then:
*
* - If 'uuid_column' is NULL, the matching row is the final row.
*
@@ -249,6 +252,7 @@ void ctl_context_done(struct ctl_context *, struct ctl_command *);
*/
struct ctl_row_id {
const struct ovsdb_idl_column *name_column;
+ const char *key;
const struct ovsdb_idl_column *uuid_column;
};
diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
index d227ceeb2..3deebfa71 100644
--- a/ovn/utilities/ovn-nbctl.c
+++ b/ovn/utilities/ovn-nbctl.c
@@ -3045,18 +3045,19 @@ cmd_set_ssl(struct ctl_context *ctx)
static const struct ctl_table_class tables[NBREC_N_TABLES] = {
[NBREC_TABLE_LOGICAL_SWITCH].row_ids[0]
- = {&nbrec_logical_switch_col_name, NULL},
+ = {&nbrec_logical_switch_col_name, NULL, NULL},
[NBREC_TABLE_LOGICAL_SWITCH_PORT].row_ids[0]
- = {&nbrec_logical_switch_port_col_name, NULL},
+ = {&nbrec_logical_switch_port_col_name, NULL, NULL},
[NBREC_TABLE_LOGICAL_ROUTER].row_ids[0]
- = {&nbrec_logical_router_col_name, NULL},
+ = {&nbrec_logical_router_col_name, NULL, NULL},
[NBREC_TABLE_LOGICAL_ROUTER_PORT].row_ids[0]
- = {&nbrec_logical_router_port_col_name, NULL},
+ = {&nbrec_logical_router_port_col_name, NULL, NULL},
- [NBREC_TABLE_ADDRESS_SET].row_ids[0] = {&nbrec_address_set_col_name, NULL},
+ [NBREC_TABLE_ADDRESS_SET].row_ids[0]
+ = {&nbrec_address_set_col_name, NULL, NULL},
};
static void
diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c
index 922ae8c4e..5d81b6b47 100644
--- a/ovn/utilities/ovn-sbctl.c
+++ b/ovn/utilities/ovn-sbctl.c
@@ -1050,15 +1050,16 @@ cmd_set_ssl(struct ctl_context *ctx)
static const struct ctl_table_class tables[SBREC_N_TABLES] = {
- [SBREC_TABLE_CHASSIS].row_ids[0] = {&sbrec_chassis_col_name, NULL},
+ [SBREC_TABLE_CHASSIS].row_ids[0] = {&sbrec_chassis_col_name, NULL, NULL},
[SBREC_TABLE_PORT_BINDING].row_ids[0] =
- {&sbrec_port_binding_col_logical_port, NULL},
+ {&sbrec_port_binding_col_logical_port, NULL, NULL},
[SBREC_TABLE_MAC_BINDING].row_ids[0] =
- {&sbrec_mac_binding_col_logical_port, NULL},
+ {&sbrec_mac_binding_col_logical_port, NULL, NULL},
- [SBREC_TABLE_ADDRESS_SET].row_ids[0] = {&sbrec_address_set_col_name, NULL},
+ [SBREC_TABLE_ADDRESS_SET].row_ids[0]
+ = {&sbrec_address_set_col_name, NULL, NULL},
};
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 3bbfba7f0..9fe3df03a 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -2291,39 +2291,41 @@ cmd_get_aa_mapping(struct ctl_context *ctx)
static const struct ctl_table_class tables[OVSREC_N_TABLES] = {
- [OVSREC_TABLE_BRIDGE].row_ids[0] = {&ovsrec_bridge_col_name, NULL},
+ [OVSREC_TABLE_BRIDGE].row_ids[0] = {&ovsrec_bridge_col_name, NULL, NULL},
[OVSREC_TABLE_CONTROLLER].row_ids[0]
- = {&ovsrec_bridge_col_name, &ovsrec_bridge_col_controller},
+ = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_controller},
- [OVSREC_TABLE_INTERFACE].row_ids[0] = {&ovsrec_interface_col_name, NULL},
+ [OVSREC_TABLE_INTERFACE].row_ids[0]
+ = {&ovsrec_interface_col_name, NULL, NULL},
- [OVSREC_TABLE_MIRROR].row_ids[0] = {&ovsrec_mirror_col_name, NULL},
+ [OVSREC_TABLE_MIRROR].row_ids[0] = {&ovsrec_mirror_col_name, NULL, NULL},
- [OVSREC_TABLE_MANAGER].row_ids[0] = {&ovsrec_manager_col_target, NULL},
+ [OVSREC_TABLE_MANAGER].row_ids[0]
+ = {&ovsrec_manager_col_target, NULL, NULL},
[OVSREC_TABLE_NETFLOW].row_ids[0]
- = {&ovsrec_bridge_col_name, &ovsrec_bridge_col_netflow},
+ = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_netflow},
- [OVSREC_TABLE_PORT].row_ids[0] = {&ovsrec_port_col_name, NULL},
+ [OVSREC_TABLE_PORT].row_ids[0] = {&ovsrec_port_col_name, NULL, NULL},
[OVSREC_TABLE_QOS].row_ids[0]
- = {&ovsrec_port_col_name, &ovsrec_port_col_qos},
+ = {&ovsrec_port_col_name, NULL, &ovsrec_port_col_qos},
[OVSREC_TABLE_SFLOW].row_ids[0]
- = {&ovsrec_bridge_col_name, &ovsrec_bridge_col_sflow},
+ = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_sflow},
[OVSREC_TABLE_FLOW_TABLE].row_ids[0]
- = {&ovsrec_flow_table_col_name, NULL},
+ = {&ovsrec_flow_table_col_name, NULL, NULL},
[OVSREC_TABLE_IPFIX].row_ids[0]
- = {&ovsrec_bridge_col_name, &ovsrec_bridge_col_ipfix},
+ = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_ipfix},
[OVSREC_TABLE_AUTOATTACH].row_ids[0]
- = {&ovsrec_bridge_col_name, &ovsrec_bridge_col_auto_attach},
+ = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_auto_attach},
[OVSREC_TABLE_FLOW_SAMPLE_COLLECTOR_SET].row_ids[0]
- = {&ovsrec_flow_sample_collector_set_col_id, NULL},
+ = {&ovsrec_flow_sample_collector_set_col_id, NULL, NULL},
};
static void
diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
index 05c9ef8e3..bbdf57fad 100644
--- a/vtep/vtep-ctl.c
+++ b/vtep/vtep-ctl.c
@@ -2178,18 +2178,19 @@ cmd_set_manager(struct ctl_context *ctx)
/* Parameter commands. */
static const struct ctl_table_class tables[VTEPREC_N_TABLES] = {
[VTEPREC_TABLE_LOGICAL_SWITCH].row_ids[0]
- = {&vteprec_logical_switch_col_name, NULL},
+ = {&vteprec_logical_switch_col_name, NULL, NULL},
- [VTEPREC_TABLE_MANAGER].row_ids[0] = {&vteprec_manager_col_target, NULL},
+ [VTEPREC_TABLE_MANAGER].row_ids[0]
+ = {&vteprec_manager_col_target, NULL, NULL},
[VTEPREC_TABLE_PHYSICAL_PORT].row_ids[0]
- = {&vteprec_physical_port_col_name, NULL},
+ = {&vteprec_physical_port_col_name, NULL, NULL},
[VTEPREC_TABLE_PHYSICAL_SWITCH].row_ids[0]
- = {&vteprec_physical_switch_col_name, NULL},
+ = {&vteprec_physical_switch_col_name, NULL, NULL},
[VTEPREC_TABLE_LOGICAL_ROUTER].row_ids[0]
- = {&vteprec_logical_router_col_name, NULL},
+ = {&vteprec_logical_router_col_name, NULL, NULL},
};