Skip to content

Commit

Permalink
ovsdb: Allow comparison on optional scalar types
Browse files Browse the repository at this point in the history
This allows things like initiating a wait request on an interface
ofport being set.

When the optional field is empty and operation is != or excludes
then the result is true; otherwise it is false. If the field is
set then the field is compared normally for its type.

Signed-off-by: Terry Wilson <[email protected]>
[[email protected] updated ovsdb-server(1) and NEWS.]
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
otherwiseguy authored and blp committed Aug 20, 2014
1 parent 886dd35 commit 09e2560
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 5 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Simon Horman [email protected]
Stephane A. Sezer [email protected]
SUGYO Kazushi [email protected]
Tadaaki Nagao [email protected]
Terry Wilson [email protected]
Tetsuo NAKAGAWA [email protected]
Thomas Goirand [email protected]
Thomas Graf [email protected]
Expand Down
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Post-v2.3.0
* OpenFlow 1.5 (draft) Copy-Field action is now supported.
* OpenFlow 1.3+ table features requests are now supported (read-only).
* Nicira extension "move" actions may now be included in action sets.
- ovsdb-server: New OVSDB protocol extension allows inequality tests on
"optional scalar" columns. See ovsdb-server(1) for details.


v2.3.0 - 14 Aug 2014
Expand Down
9 changes: 9 additions & 0 deletions lib/ovsdb-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ bool ovsdb_type_is_valid(const struct ovsdb_type *);

static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *);
static inline bool ovsdb_type_is_optional(const struct ovsdb_type *);
static inline bool ovsdb_type_is_optional_scalar(
const struct ovsdb_type *);
static inline bool ovsdb_type_is_composite(const struct ovsdb_type *);
static inline bool ovsdb_type_is_set(const struct ovsdb_type *);
static inline bool ovsdb_type_is_map(const struct ovsdb_type *);
Expand Down Expand Up @@ -202,6 +204,13 @@ static inline bool ovsdb_type_is_optional(const struct ovsdb_type *type)
return type->n_min == 0;
}

static inline bool ovsdb_type_is_optional_scalar(
const struct ovsdb_type *type)
{
return (type->value.type == OVSDB_TYPE_VOID
&& type->n_min == 0 && type->n_max == 1);
}

static inline bool ovsdb_type_is_composite(const struct ovsdb_type *type)
{
return type->n_max > 1;
Expand Down
24 changes: 19 additions & 5 deletions ovsdb/condition.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts,
case OVSDB_F_LE:
case OVSDB_F_GT:
case OVSDB_F_GE:
/* XXX should we also allow these operators for types with n_min == 0,
* n_max == 1? (They would always be "false" if the value was
* missing.) */
if (!ovsdb_type_is_scalar(&type)
/* Allow these operators for types with n_min == 0, n_max == 1.
* (They will always be "false" if the value is missing.) */
if (!(ovsdb_type_is_scalar(&type)
|| ovsdb_type_is_optional_scalar(&type))
|| (type.key.type != OVSDB_TYPE_INTEGER
&& type.key.type != OVSDB_TYPE_REAL)) {
char *s = ovsdb_type_to_english(&type);
Expand Down Expand Up @@ -225,7 +225,21 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row,
const struct ovsdb_datum *arg = &c->arg;
const struct ovsdb_type *type = &c->column->type;

if (ovsdb_type_is_scalar(type)) {
if (ovsdb_type_is_optional_scalar(type) && field->n == 0) {
switch (c->function) {
case OVSDB_F_LT:
case OVSDB_F_LE:
case OVSDB_F_EQ:
case OVSDB_F_GE:
case OVSDB_F_GT:
case OVSDB_F_INCLUDES:
return false;
case OVSDB_F_NE:
case OVSDB_F_EXCLUDES:
return true;
}
} else if (ovsdb_type_is_scalar(type)
|| ovsdb_type_is_optional_scalar(type)) {
int cmp = ovsdb_atom_compare_3way(&field->keys[0], &arg->keys[0],
type->key.type);
switch (c->function) {
Expand Down
9 changes: 9 additions & 0 deletions ovsdb/ovsdb-server.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@ notifications (see below) to the request, it must be unique among all
active monitors. \fBovsdb\-server\fR rejects attempt to create two
monitors with the same identifier.
.
.IP "5.1. Notation"
For <condition>, RFC 7047 only allows the use of \fB!=\fR, \fB==\fR,
\fBincludes\fR, and \fBexcludes\fR operators with set types. Open
vSwitch 2.4 and later extend <condition> to allow the use of \fB<\fR,
\fB<=\fR, \fB>=\fR, and \fB>\fR operators with columns with type ``set
of 0 or 1 integer'' and ``set of 0 or 1 real''. These conditions
evaluate to false when the column is empty, and otherwise as described
in RFC 7047 for integer and real types.
.
.IP "6. IANA Considerations"
\fBovsdb\-server\fR currently defaults to its historical port number
6632. Future versions will adopt IANA-assigned port 6640 as default.
Expand Down
81 changes: 81 additions & 0 deletions tests/ovsdb-condition.at
Original file line number Diff line number Diff line change
Expand Up @@ -576,3 +576,84 @@ condition 29: T-TTT ---T- -----
condition 30: TTT-T -T-T- T----
condition 31: T-T-T ---T- -----
condition 32: ----- T---- ---T-], [condition])

OVSDB_CHECK_POSITIVE([evaluating conditions on optional integers],
[[evaluate-conditions \
'{"columns": {"i": {"type": {"key": "integer", "min": 0, "max": 1}}}}' \
'[[["i", "<", 1]],
[["i", "<=", 1]],
[["i", "==", 1]],
[["i", "!=", 1]],
[["i", ">=", 1]],
[["i", ">", 1]],
[["i", "includes", 1]],
[["i", "excludes", 1]],
[["i", ">", 0], ["i", "<", 2]]]' \
'[{"i": ["set", []]},
{"i": ["set", [0]]},
{"i": ["set", [1]]},
{"i": ["set", [2]]}]']],
[dnl
condition 0: -T--
condition 1: -TT-
condition 2: --T-
condition 3: TT-T
condition 4: --TT
condition 5: ---T
condition 6: --T-
condition 7: TT-T
condition 8: --T-], [condition])

OVSDB_CHECK_POSITIVE([evaluating conditions on optional strings],
[[evaluate-conditions \
'{"columns": {"s": {"type": {"key": "string", "min": 0, "max": 1}}}}' \
'[[["s", "==", ""]],
[["s", "!=", ""]],
[["s", "includes", ""]],
[["s", "excludes", ""]],
[["s", "==", "foo"]],
[["s", "!=", "foo"]],
[["s", "includes", "foo"]],
[["s", "excludes", "foo"]],
[["s", "!=", "foo"], ["s", "!=", ""]]]' \
'[{"s": ["set", [""]]},
{"s": ["set", ["foo"]]},
{"s": ["set", ["xxx"]]},
{"s": ["set", []]}]']],
[dnl
condition 0: T---
condition 1: -TTT
condition 2: T---
condition 3: -TTT
condition 4: -T--
condition 5: T-TT
condition 6: -T--
condition 7: T-TT
condition 8: --TT], [condition])

OVSDB_CHECK_POSITIVE([evaluating conditions on optional reals],
[[evaluate-conditions \
'{"columns": {"r": {"type": {"key": "real", "min": 0, "max": 1}}}}' \
'[[["r", "<", 5.0]],
[["r", "<=", 5.0]],
[["r", "==", 5.0]],
[["r", "!=", 5.0]],
[["r", ">=", 5.0]],
[["r", ">", 5.0]],
[["r", "includes", 5.0]],
[["r", "excludes", 5.0]],
[["r", "!=", 0], ["r", "!=", 5.1]]]' \
'[{"r": ["set", [0]]},
{"r": ["set", [5.0]]},
{"r": ["set", [5.1]]},
{"r": ["set", []]}]']],
[dnl
condition 0: T---
condition 1: TT--
condition 2: -T--
condition 3: T-TT
condition 4: -TT-
condition 5: --T-
condition 6: -T--
condition 7: T-TT
condition 8: -T-T], [condition])

0 comments on commit 09e2560

Please sign in to comment.