2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

nx-match: Trim variable length fields when encoding as actions.

It is technically correct to send the entire maximum length of
a field when it is variable length. However, it is awkward to
do so and not what one would naively expect. Since receivers will
internally zero-extend fields, we can do the opposite and trim
off leading zeros. This results in encodings that are generally
sensible without specific knowledge of what is being transmitted.
(Of course, other implementations, such as controllers, may know
exactly the expected length of the field and are free to encode
it that way even if it has leading zeros.)

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Jesse Gross
2015-05-06 18:05:18 -07:00
parent dc3eb9539f
commit 4ede8c79eb
3 changed files with 57 additions and 7 deletions

View File

@@ -1013,6 +1013,48 @@ mf_mask_field(const struct mf_field *mf, struct flow *mask)
}
}
static int
field_len(const struct mf_field *mf, const union mf_value *value_)
{
const uint8_t *value = &value_->u8;
int i;
if (!mf->variable_len) {
return mf->n_bytes;
}
if (!value) {
return 0;
}
for (i = 0; i < mf->n_bytes; i++) {
if (value[i] != 0) {
break;
}
}
return mf->n_bytes - i;
}
/* Returns the effective length of the field. For fixed length fields,
* this is just the defined length. For variable length fields, it is
* the minimum size encoding that retains the same meaning (i.e.
* discarding leading zeros). */
int
mf_field_len(const struct mf_field *mf, const union mf_value *value,
const union mf_value *mask)
{
int len, mask_len;
len = field_len(mf, value);
if (mask && !is_all_ones(mask, mf->n_bytes)) {
mask_len = field_len(mf, mask);
len = MAX(len, mask_len);
}
return len;
}
/* Sets 'flow' member field described by 'mf' to 'value'. The caller is
* responsible for ensuring that 'flow' meets 'mf''s prerequisites.*/
void