X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fmeta-flow.c;h=78715458681401c1da3af8b2bc3ea11da001dd20;hb=7eb4b1f1d70345f44ac7f3de89eb0340a5cafb71;hp=5056be5ae64faa55c3134e5d63e6672bd4187e9f;hpb=ebeae5db715dd4a33a6918765505b5695f938fce;p=cascardo%2Fovs.git diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 5056be5ae..787154586 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1076,6 +1076,36 @@ mf_set_flow_value(const struct mf_field *mf, } } +/* Consider each of 'src', 'mask', and 'dst' as if they were arrays of 8*n + * bits. Then, for each 0 <= i < 8 * n such that mask[i] == 1, sets dst[i] = + * src[i]. */ +static void +apply_mask(const uint8_t *src, const uint8_t *mask, uint8_t *dst, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = (src[i] & mask[i]) | (dst[i] & ~mask[i]); + } +} + +/* Sets 'flow' member field described by 'field' to 'value', except that bits + * for which 'mask' has a 0-bit keep their existing values. The caller is + * responsible for ensuring that 'flow' meets 'field''s prerequisites.*/ +void +mf_set_flow_value_masked(const struct mf_field *field, + const union mf_value *value, + const union mf_value *mask, + struct flow *flow) +{ + union mf_value tmp; + + mf_get_value(field, flow, &tmp); + apply_mask((const uint8_t *) value, (const uint8_t *) mask, + (uint8_t *) &tmp, field->n_bytes); + mf_set_flow_value(field, &tmp, flow); +} + /* Returns true if 'mf' has a zero value in 'flow', false if it is nonzero. * * The caller is responsible for ensuring that 'flow' meets 'mf''s