diff --git a/Makefile b/Makefile index 1d45f17..d4b623f 100644 --- a/Makefile +++ b/Makefile @@ -50,11 +50,18 @@ HEADERS = $(PASST_HEADERS) seccomp.h # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78993 # from the pointer arithmetic used from the tcp_tap_handler() path to get the # remote connection address. +# +# TODO: With the same combination, in ndp(), gcc optimises away the store of +# hop_limit in the IPv6 header (temporarily set to the protocol number for +# convenience, to mimic the ICMPv6 checksum pseudo-header) before the call to +# csum_unaligned(). Mark csum_unaligned() as "noipa" as a quick work-around, +# while we figure out if a corresponding gcc issue has already been reported. ifeq (,$(filter-out 11 12, $(shell $(CC) -dumpversion))) ifneq (,$(filter -flto%,$(FLAGS) $(CFLAGS))) ifneq (,$(filter -O2,$(FLAGS) $(CFLAGS))) FLAGS += -DTCP_HASH_NOINLINE FLAGS += -DSIPHASH_20B_NOINLINE + FLAGS += -DCSUM_UNALIGNED_NO_IPA endif endif endif diff --git a/checksum.c b/checksum.c index acb1e3e..56ad01e 100644 --- a/checksum.c +++ b/checksum.c @@ -97,6 +97,9 @@ uint16_t csum_fold(uint32_t sum) * * Return: 16-bit IPv4-style checksum */ +#if CSUM_UNALIGNED_NO_IPA +__attribute__((__noipa__)) /* See comment in Makefile */ +#endif uint16_t csum_unaligned(const void *buf, size_t len, uint32_t init) { return (uint16_t)~csum_fold(sum_16b(buf, len) + init);