summaryrefslogtreecommitdiff
path: root/include/openvswitch/ofp-actions.h
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2016-09-02 13:26:50 -0700
committerBen Pfaff <blp@ovn.org>2016-09-02 15:55:00 -0700
commitc65a31e2622402bcb1b0b8df0ab928b83a0ed4a0 (patch)
treee6a082cad0601119035e5d71f18dde9bc879e9a8 /include/openvswitch/ofp-actions.h
parent784bf5d4eb3ce41c93927991d57ef6522363cd76 (diff)
downloadopenvswitch-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.h33
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. */