diff options
author | Ben Pfaff <blp@ovn.org> | 2016-09-02 13:26:50 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-09-02 15:55:00 -0700 |
commit | c65a31e2622402bcb1b0b8df0ab928b83a0ed4a0 (patch) | |
tree | e6a082cad0601119035e5d71f18dde9bc879e9a8 /include/openvswitch/ofp-actions.h | |
parent | 784bf5d4eb3ce41c93927991d57ef6522363cd76 (diff) | |
download | openvswitch-c65a31e2622402bcb1b0b8df0ab928b83a0ed4a0.tar.gz |
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: dfe191d5faa6 ("ofp-actions: Waste less memory in learn actions.")
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Jarno Rajahalme <jarno@ovn.org>
Diffstat (limited to 'include/openvswitch/ofp-actions.h')
-rw-r--r-- | include/openvswitch/ofp-actions.h | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h index bf7d62fc1..675920173 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. */ |