Due to what looks like a rebasing error, this patch doesn't compile. I haven't read the code yet.
Ethan On Wed, Apr 11, 2012 at 17:15, Ben Pfaff <b...@nicira.com> wrote: > The existing functions for reading and writing the values of subfields only > handle subfields up to 64 bits wide. These new functions handle subfields > of any width. > > Signed-off-by: Ben Pfaff <b...@nicira.com> > --- > lib/meta-flow.c | 41 ++++++++++++++++++++++++++++++++++++----- > lib/meta-flow.h | 20 ++++++++++++++++++++ > 2 files changed, 56 insertions(+), 5 deletions(-) > > diff --git a/lib/meta-flow.c b/lib/meta-flow.c > index 11d27b1..a8cfd74 100644 > --- a/lib/meta-flow.c > +++ b/lib/meta-flow.c > @@ -2241,12 +2241,27 @@ mf_format(const struct mf_field *mf, > } > } > > -/* Makes a subfield starting at bit offset 'ofs' and continuing for 'n_bits' > in > - * 'rule''s field 'mf' exactly match the 'n_bits' least-significant bits of > - * 'x'. > +/* Makes subfield 'sf' within 'rule' exactly match the 'sf->n_bits' > + * least-significant bits in 'x'. > * > - * Example: suppose that 'mf' is originally the following 2-byte field in > - * 'rule': > + * See mf_set_subfield() for an example. > + * > + * The difference between this function and mf_set_subfield() is that the > + * latter function can only handle subfields up to 64 bits wide, whereas this > + * one handles the general case. On the other hand, mf_set_subfield() is > + * arguably easier to use. */ > +void > +mf_write_subfield(const struct mf_subfield *sf, const union mf_subvalue *x, > + struct cls_rule *rule) > +{ > + const struct mf_field *field = sf->field; > + union mf_value value, mask; > + > + mf_get(field, rule, &value, &mask); > + bitwise_copy(x, sizeof *x, 0, &value, field->n_bytes, sf->ofs, > sf->n_bits); > + bitwise_one ( &mask, field->n_bytes, sf->ofs, > sf->n_bits); > + mf_set(field, &value, &mask, rule); > +} > * > * value == 0xe00a == 2#1110000000001010 > * mask == 0xfc3f == 2#1111110000111111 > @@ -2314,6 +2329,22 @@ mf_set_subfield_value(const struct mf_subfield *sf, > uint64_t x, > } > } > > +/* Initializes 'x' to the value of 'sf' within 'flow'. 'sf' must be valid > for > + * reading 'flow', e.g. as checked by mf_check_src(). */ > +void > +mf_read_subfield(const struct mf_subfield *sf, const struct flow *flow, > + union mf_subvalue *x) > +{ > + union mf_value value; > + > + mf_get_value(sf->field, flow, &value); > + > + memset(x, 0, sizeof *x); > + bitwise_copy(&value, sf->field->n_bytes, sf->ofs, > + x, sizeof *x, 0, > + sf->n_bits); > +} > + > /* Returns the value of 'sf' within 'flow'. 'sf' must be valid for reading > * 'flow', e.g. as checked by mf_check_src() and sf->n_bits must be 64 or > * less. */ > diff --git a/lib/meta-flow.h b/lib/meta-flow.h > index e062312..91d52c7 100644 > --- a/lib/meta-flow.h > +++ b/lib/meta-flow.h > @@ -207,6 +207,7 @@ union mf_value { > uint8_t mac[ETH_ADDR_LEN]; > struct in6_addr ipv6; > }; > +BUILD_ASSERT_DECL(sizeof(union mf_value) == 16); > > /* Part of a field. */ > struct mf_subfield { > @@ -215,6 +216,19 @@ struct mf_subfield { > unsigned int n_bits; /* Number of bits. */ > }; > > +/* Data for some part of an mf_field. > + * > + * The data is stored "right-justified". For example, if "union mf_subvalue > + * value" contains NXM_OF_VLAN_TCI[0..11], then one could access the > + * corresponding data in value.be16[7] as the bits in the mask htons(0xfff). > */ > +union mf_subvalue { > + uint8_t u8[16]; > + ovs_be16 be16[8]; > + ovs_be32 be32[4]; > + ovs_be64 be64[2]; > +}; > +BUILD_ASSERT_DECL(sizeof(union mf_value) == sizeof (union mf_subvalue)); > + > /* Finding mf_fields. */ > const struct mf_field *mf_from_id(enum mf_field_id); > const struct mf_field *mf_from_name(const char *name); > @@ -253,12 +267,18 @@ void mf_set_wild(const struct mf_field *, struct > cls_rule *); > void mf_random_value(const struct mf_field *, union mf_value *value); > > /* Subfields. */ > +void mf_write_subfield(const struct mf_subfield *, const union mf_subvalue *, > + struct cls_rule *); > void mf_set_subfield(const struct mf_subfield *, uint64_t value, > struct cls_rule *); > void mf_set_subfield_value(const struct mf_subfield *, uint64_t value, > struct flow *); > + > +void mf_read_subfield(const struct mf_subfield *, const struct flow *, > + union mf_subvalue *); > uint64_t mf_get_subfield(const struct mf_subfield *, const struct flow *); > > + > void mf_format_subfield(const struct mf_subfield *, struct ds *); > char *mf_parse_subfield__(struct mf_subfield *sf, const char **s); > const char *mf_parse_subfield(struct mf_subfield *, const char *); > -- > 1.7.2.5 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev