Thanks, applied to master and branch-2.6.
On Fri, Sep 02, 2016 at 03:49:59PM -0700, Jarno Rajahalme wrote: > Good catch (== thanks for finding an embarrassing bug to mine :-) > > Acked-by: Jarno Rajahalme <ja...@ovn.org> > > > On Sep 2, 2016, at 1:26 PM, Ben Pfaff <b...@ovn.org> wrote: > > > > struct ofpact_learn_spec is variable-length. The 'n_specs' member of > > struct ofpact_learn counted the number of specs, but the iteration loops > > over struct ofpact_learn_spec only iterated as far as the *minimum* length > > of 'n_specs' specs. > > > > This fixes the problem, which exhibited as consistent failures for test 431 > > (learning action - TCPv6 port learning), seemingly only on i386 since it > > shows up for my personal development machine but appears to not happen for > > anyone else. > > > > Fixes: dfe191d5faa6 ("ofp-actions: Waste less memory in learn actions.") > > Signed-off-by: Ben Pfaff <b...@ovn.org> > > --- > > include/openvswitch/ofp-actions.h | 33 +++++++++++++++++++++++---------- > > lib/learn.c | 13 ++++--------- > > lib/ofp-actions.c | 4 +--- > > 3 files changed, 28 insertions(+), 22 deletions(-) > > > > diff --git a/include/openvswitch/ofp-actions.h > > b/include/openvswitch/ofp-actions.h > > index bf7d62f..6759201 100644 > > --- a/include/openvswitch/ofp-actions.h > > +++ b/include/openvswitch/ofp-actions.h > > @@ -744,21 +744,34 @@ ofpact_learn_spec_next(const struct ofpact_learn_spec > > *spec) > > * > > * Used for NXAST_LEARN. */ > > struct ofpact_learn { > > - struct ofpact ofpact; > > + OFPACT_PADDED_MEMBERS( > > + struct ofpact ofpact; > > > > - uint16_t idle_timeout; /* Idle time before discarding (seconds). > > */ > > - uint16_t hard_timeout; /* Max time before discarding (seconds). */ > > - uint16_t priority; /* Priority level of flow entry. */ > > - uint8_t table_id; /* Table to insert flow entry. */ > > - enum nx_learn_flags flags; /* NX_LEARN_F_*. */ > > - ovs_be64 cookie; /* Cookie for new flow. */ > > - uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */ > > - uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */ > > + uint16_t idle_timeout; /* Idle time before discarding > > (seconds). */ > > + uint16_t hard_timeout; /* Max time before discarding > > (seconds). */ > > + uint16_t priority; /* Priority level of flow entry. */ > > + uint8_t table_id; /* Table to insert flow entry. */ > > + enum nx_learn_flags flags; /* NX_LEARN_F_*. */ > > + ovs_be64 cookie; /* Cookie for new flow. */ > > + uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. > > */ > > + uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. > > */ > > + ); > > > > - unsigned int n_specs; > > struct ofpact_learn_spec specs[]; > > }; > > > > +static inline const struct ofpact_learn_spec * > > +ofpact_learn_spec_end(const struct ofpact_learn *learn) > > +{ > > + return ALIGNED_CAST(const struct ofpact_learn_spec *, > > + ofpact_next(&learn->ofpact)); > > +} > > + > > +#define OFPACT_LEARN_SPEC_FOR_EACH(SPEC, LEARN) \ > > + for ((SPEC) = (LEARN)->specs; \ > > + (SPEC) < ofpact_learn_spec_end(LEARN); \ > > + (SPEC) = ofpact_learn_spec_next(SPEC)) > > + > > /* Multipath link choice algorithm to apply. > > * > > * In the descriptions below, 'n_links' is max_link + 1. */ > > diff --git a/lib/learn.c b/lib/learn.c > > index bb57f7d..9cab759 100644 > > --- a/lib/learn.c > > +++ b/lib/learn.c > > @@ -41,8 +41,7 @@ learn_check(const struct ofpact_learn *learn, const > > struct flow *flow) > > struct match match; > > > > match_init_catchall(&match); > > - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; > > - spec = ofpact_learn_spec_next(spec)) { > > + OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) { > > enum ofperr error; > > > > /* Check the source. */ > > @@ -123,8 +122,7 @@ learn_execute(const struct ofpact_learn *learn, const > > struct flow *flow, > > oft->fin_hard_timeout = learn->fin_hard_timeout; > > } > > > > - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; > > - spec = ofpact_learn_spec_next(spec)) { > > + OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) { > > struct ofpact_set_field *sf; > > union mf_subvalue value; > > > > @@ -179,8 +177,7 @@ learn_mask(const struct ofpact_learn *learn, struct > > flow_wildcards *wc) > > union mf_subvalue value; > > > > memset(&value, 0xff, sizeof value); > > - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; > > - spec = ofpact_learn_spec_next(spec)) { > > + OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) { > > if (spec->src_type == NX_LEARN_SRC_FIELD) { > > mf_write_subfield_flow(&spec->src, &value, &wc->masks); > > } > > @@ -386,7 +383,6 @@ learn_parse__(char *orig, char *arg, struct ofpbuf > > *ofpacts) > > return error; > > } > > learn = ofpacts->header; > > - learn->n_specs++; > > } > > } > > ofpact_finish_LEARN(ofpacts, &learn); > > @@ -459,8 +455,7 @@ learn_format(const struct ofpact_learn *learn, struct > > ds *s) > > colors.param, colors.end, ntohll(learn->cookie)); > > } > > > > - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; > > - spec = ofpact_learn_spec_next(spec)) { > > + OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) { > > unsigned int n_bytes = DIV_ROUND_UP(spec->n_bits, 8); > > ds_put_char(s, ','); > > > > diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c > > index f27ff21..22c7b16 100644 > > --- a/lib/ofp-actions.c > > +++ b/lib/ofp-actions.c > > @@ -4321,7 +4321,6 @@ decode_NXAST_RAW_LEARN(const struct nx_action_learn > > *nal, > > > > spec = ofpbuf_put_zeros(ofpacts, sizeof *spec); > > learn = ofpacts->header; > > - learn->n_specs++; > > > > spec->src_type = header & NX_LEARN_SRC_MASK; > > spec->dst_type = header & NX_LEARN_DST_MASK; > > @@ -4421,8 +4420,7 @@ encode_LEARN(const struct ofpact_learn *learn, > > nal->flags = htons(learn->flags); > > nal->table_id = learn->table_id; > > > > - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; > > - spec = ofpact_learn_spec_next(spec)) { > > + OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) { > > put_u16(out, spec->n_bits | spec->dst_type | spec->src_type); > > > > if (spec->src_type == NX_LEARN_SRC_FIELD) { > > -- > > 2.1.3 > > > > _______________________________________________ > > dev mailing list > > dev@openvswitch.org > > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev