Systemd/src/libsystemd-network/radv-internal.h
Zbigniew Jędrzejewski-Szmek e27b9aba30 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.
2019-02-04 20:32:44 +01:00

104 lines
3.2 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
Copyright © 2017 Intel Corporation. All rights reserved.
***/
#include "sd-radv.h"
#include "log.h"
#include "list.h"
#include "sparse-endian.h"
assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS 3
#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS 3
#define SD_RADV_MIN_DELAY_BETWEEN_RAS 3
#define SD_RADV_MAX_RA_DELAY_TIME_USEC (500*USEC_PER_MSEC)
#define SD_RADV_OPT_RDNSS 25
#define SD_RADV_OPT_DNSSL 31
enum RAdvState {
SD_RADV_STATE_IDLE = 0,
SD_RADV_STATE_ADVERTISING = 1,
};
typedef enum RAdvState RAdvState;
struct sd_radv_opt_dns {
uint8_t type;
uint8_t length;
uint16_t reserved;
be32_t lifetime;
} _packed_;
struct sd_radv {
unsigned n_ref;
RAdvState state;
int ifindex;
sd_event *event;
int event_priority;
struct ether_addr mac_addr;
uint8_t hop_limit;
uint8_t flags;
uint32_t mtu;
uint16_t lifetime;
int fd;
unsigned ra_sent;
sd_event_source *recv_event_source;
sd_event_source *timeout_event_source;
unsigned n_prefixes;
LIST_HEAD(sd_radv_prefix, prefixes);
size_t n_rdnss;
struct sd_radv_opt_dns *rdnss;
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 radv_prefix_opt opt;
LIST_FIELDS(struct sd_radv_prefix, prefix);
usec_t valid_until;
usec_t preferred_until;
};
#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)