mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
learn: Fix iteration over learning specs.
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: dfe191d5fa
("ofp-actions: Waste less memory in learn actions.")
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Jarno Rajahalme <jarno@ovn.org>
This commit is contained in:
13
lib/learn.c
13
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, ',');
|
||||
|
||||
|
Reference in New Issue
Block a user