libsystemd-network: remove _packed_ attribute to appease the compiler

gcc-9 warns whenever the elements of a structure defined with _packed_ are used:

../src/network/networkd-dhcp6.c: In function ‘dhcp6_pd_prefix_assign’:
../src/network/networkd-dhcp6.c:92:53: warning: taking address of packed member of ‘struct <anonymous>’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   92 |         r = manager_dhcp6_prefix_add(link->manager, &p->opt.in6_addr, link);
      |                                                     ^~~~~~~~~~~~~~~~

And the compiler is right, because in principle the alignment could be wrong.
In this particular case it is not, because the structure is carefully defined
not to have holes. Let's remove _packed_ and use compile-time asserts to verify
that the offsets are not changed.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-01-27 17:09:21 +01:00
parent 00e1adf8b1
commit e27b9aba30
1 changed files with 25 additions and 10 deletions

View File

@ -63,19 +63,34 @@ struct sd_radv {
struct sd_radv_opt_dns *dnssl;
};
#define radv_prefix_opt__contents { \
uint8_t type; \
uint8_t length; \
uint8_t prefixlen; \
uint8_t flags; \
be32_t valid_lifetime; \
be32_t preferred_lifetime; \
uint32_t reserved; \
struct in6_addr in6_addr; \
}
struct radv_prefix_opt radv_prefix_opt__contents;
/* We need the opt substructure to be packed, because we use it in send(). But
* if we use _packed_, this means that the structure cannot be used directly in
* normal code in general, because the fields might not be properly aligned.
* But in this particular case, the structure is defined in a way that gives
* proper alignment, even without the explicit _packed_ attribute. To appease
* the compiler we use the "unpacked" structure, but we also verify that
* structure contains no holes, so offsets are the same when _packed_ is used.
*/
struct radv_prefix_opt__packed radv_prefix_opt__contents _packed_;
assert_cc(sizeof(struct radv_prefix_opt) == sizeof(struct radv_prefix_opt__packed));
struct sd_radv_prefix {
unsigned n_ref;
struct {
uint8_t type;
uint8_t length;
uint8_t prefixlen;
uint8_t flags;
be32_t valid_lifetime;
be32_t preferred_lifetime;
uint32_t reserved;
struct in6_addr in6_addr;
} _packed_ opt;
struct radv_prefix_opt opt;
LIST_FIELDS(struct sd_radv_prefix, prefix);