From 9193d14524c4408c0d3d5aab4752f44852285e6f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 18 Feb 2016 10:12:04 -0800 Subject: [PATCH] ofp-actions: Introduce macro for padding struct members. An upcoming commit will add another case where it's desirable to ensure that a variable-length array is aligned on an 8-byte boundary. This macro makes that a little easier. Signed-off-by: Ben Pfaff CC: Joe Stringer Acked-by: Joe Stringer --- lib/ofp-actions.h | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index 58d7857bc..24143d324 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -185,6 +185,19 @@ BUILD_ASSERT_DECL(sizeof(struct ofpact) == 4); #define OFPACT_ALIGNTO 8 #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO) +/* Expands to an anonymous union that contains: + * + * - MEMBERS in a nested anonymous struct. + * + * - An array as large as MEMBERS plus padding to a multiple of 8 bytes. + * + * The effect is to pad MEMBERS to a multiple of 8 bytes. */ +#define OFPACT_PADDED_MEMBERS(MEMBERS) \ + union { \ + struct { MEMBERS }; \ + uint8_t pad[OFPACT_ALIGN(sizeof(struct { MEMBERS }))]; \ + } + /* Returns the ofpact following 'ofpact'. */ static inline struct ofpact * ofpact_next(const struct ofpact *ofpact) @@ -487,8 +500,7 @@ struct ofpact_meter { * * Used for OFPIT11_WRITE_ACTIONS. */ struct ofpact_nest { - struct ofpact ofpact; - uint8_t pad[PAD_SIZE(sizeof(struct ofpact), OFPACT_ALIGNTO)]; + OFPACT_PADDED_MEMBERS(struct ofpact ofpact;); struct ofpact actions[]; }; BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) % OFPACT_ALIGNTO == 0); @@ -507,21 +519,6 @@ enum nx_conntrack_flags { * 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; \ - uint16_t alg; \ - uint8_t recirc_table; \ -} - #if !defined(IPPORT_FTP) #define IPPORT_FTP 21 #endif @@ -530,10 +527,14 @@ struct { \ * * Used for NXAST_CT. */ struct ofpact_conntrack { - union { - CT_MEMBERS; - uint8_t pad[OFPACT_ALIGN(sizeof(CT_MEMBERS))]; - }; + OFPACT_PADDED_MEMBERS( + struct ofpact ofpact; + uint16_t flags; + uint16_t zone_imm; + struct mf_subfield zone_src; + uint16_t alg; + uint8_t recirc_table; + ); struct ofpact actions[0]; }; BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack, actions) -- 2.20.1