* that the packet should not be recirculated. */
#define NX_CT_RECIRC_NONE OFPTT_ALL
+/* We want to determine the size of these elements at compile time to ensure
+ * actions alignment, but we also want to allow ofpact_conntrack to have
+ * basic _put(), _get(), etc accessors defined below which access these
+ * members directly from ofpact_conntrack. An anonymous struct will serve
+ * both of these purposes. */
+#define CT_MEMBERS \
+struct { \
+ struct ofpact ofpact; \
+ uint16_t flags; \
+ uint16_t zone_imm; \
+ struct mf_subfield zone_src; \
+ uint8_t recirc_table; \
+}
+
/* OFPACT_CT.
*
* Used for NXAST_CT. */
struct ofpact_conntrack {
- struct ofpact ofpact;
- uint16_t flags;
- uint16_t zone_imm;
- struct mf_subfield zone_src;
- uint8_t recirc_table;
+ union {
+ CT_MEMBERS;
+ uint8_t pad[OFPACT_ALIGN(sizeof(CT_MEMBERS))];
+ };
+ struct ofpact actions[];
};
+BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack, actions)
+ % OFPACT_ALIGNTO == 0);
+BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack, actions)
+ == sizeof(struct ofpact_conntrack));
+
+static inline size_t
+ofpact_ct_get_action_len(const struct ofpact_conntrack *oc)
+{
+ return oc->ofpact.len - offsetof(struct ofpact_conntrack, actions);
+}
static inline size_t
ofpact_nest_get_action_len(const struct ofpact_nest *on)