Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ src/tests/qemu/distfiles/
src/crypto/zinc/*/*.S
src/amneziawg.mod
src/generated
src/kernel
src/kernel
.cache
compile_commands.json
16 changes: 10 additions & 6 deletions src/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
#
# Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.

AWG_MODERN_KERNEL := $(shell [ $(VERSION) -gt 5 -o \( $(VERSION) -eq 5 -a $(PATCHLEVEL) -gt 5 \) ] && echo true)

ccflags-y := -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt'
ccflags-y += -Wframe-larger-than=2048
ccflags-$(CONFIG_AMNEZIAWG_DEBUG) += -DDEBUG -g
ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"'
ccflags-$(if $(OMIT_ENDPOINTS),y,) += -D'OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)"'

amneziawg-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o
amneziawg-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o junk.o magic_header.o

ifeq ($(shell [ $(VERSION) -lt 6 -o \( $(VERSION) -eq 6 -a $(PATCHLEVEL) -lt 1 \) ] && echo y),y)
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
else
kbuild-dir := $(src)
endif

ifndef AWG_MODERN_KERNEL
include $(src)/crypto/Kbuild.include
include $(src)/compat/Kbuild.include
ifeq ($(shell [ $(VERSION) -lt 5 -o \( $(VERSION) -eq 5 -a $(PATCHLEVEL) -lt 10 \) ] && echo y),y)
include $(src)/crypto/Kbuild.include
endif
include $(src)/compat/Kbuild.include

obj-$(if $(KBUILD_EXTMOD),m,$(CONFIG_AMNEZIAWG)) := amneziawg.o
82 changes: 6 additions & 76 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,94 +16,24 @@ DEPMODBASEDIR ?= /

PWD := $(shell pwd)

all: apply-patches module
debug: apply-patches module-debug

rwildcard=$(foreach d,$(if $3,$(filter-out $3,$(wildcard $1*)),$(wildcard $1*)),$(call rwildcard,$d/,$2,$3) $(filter $(subst *,%,$2),$d))

KERNEL_SOURCE_DIR := $(PWD)/kernel
WG_SOURCE_DIR := $(KERNEL_SOURCE_DIR)/drivers/net/wireguard

define MODERN_KERNEL_CHECK_COMMAND
echo $(KERNELRELEASE) | awk 'BEGIN{ FS="."};
{ if ($$1 < 5) { print "N"; }
else if ($$1 == 5) {
if ($$2 <= 5) { print "N"; }
else { print "Y"; }
}
else { print "Y"; }
}'
endef
export MODERN_KERNEL_CHECK_COMMAND

ifeq ($(shell $(MODERN_KERNEL_CHECK_COMMAND)),Y)
define MODERN_KERNEL_SOURCES_NOT_FOUND_ERROR

You're running a modern Linux Kernel (version $(KERNELRELEASE)).

In order to build AmneziaWG kernel module for this kernel you must obtain sources of your kernel
by yourself and make a symlink to them into this directory:

ln -s <path to kernel sources> kernel

After that please run make script again
endef
export MODERN_KERNEL_SOURCES_NOT_FOUND_ERROR

GENERATED_SOURCES_DIR := $(PWD)/generated
TARGET_BUILD_DIR := $(GENERATED_SOURCES_DIR)

FILE_LIST := $(if $(strip $(realpath $(WG_SOURCE_DIR))),$(call rwildcard,$(WG_SOURCE_DIR)/,*.c *.h *.S *.pl *.include,))
SOURCE_FILES := $(filter-out Makefile main.c wireguard.mod.c tests/%,$(foreach f,$(FILE_LIST),$(subst $(WG_SOURCE_DIR)/,,$(f))))
NEEDED_SOURCES := $(addprefix $(GENERATED_SOURCES_DIR)/,main.c uapi/wireguard.h Kbuild Kconfig $(SOURCE_FILES))

apply-patches: $(NEEDED_SOURCES) $(GENERATED_SOURCES_DIR)/.patches.stamp

$(GENERATED_SOURCES_DIR)/.patches.stamp: $(sort $(wildcard $(PWD)/patches/*.patch))
CWD=$$(pwd); \
cd $(GENERATED_SOURCES_DIR); \
for patch in $^; do \
patch -F3 -t -p0 -i $$patch; \
done; \
cd $$CWD; \
date > $(GENERATED_SOURCES_DIR)/.patches.stamp

$(GENERATED_SOURCES_DIR)/K%: $(PWD)/K%
@install -d $(@D) && install -m 0644 $^ $@

$(GENERATED_SOURCES_DIR)/uapi/wireguard.h: $(KERNEL_SOURCE_DIR)/include/uapi/linux/wireguard.h
@install -d $(@D) && install -m 0644 $^ $@

$(GENERATED_SOURCES_DIR)/%: $(WG_SOURCE_DIR)/%
@install -d $(@D) && install -m 0644 $^ $@

$(KERNEL_SOURCE_DIR)/%:
$(error $(MODERN_KERNEL_SOURCES_NOT_FOUND_ERROR))
else
TARGET_BUILD_DIR := $(PWD)

apply-patches:
@:
endif
all: module
debug: module-debug

ifneq ($(V),1)
MAKEFLAGS += --no-print-directory
endif

module:
@$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules
[ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko || true
@$(MAKE) -C $(KERNELDIR) M=$(PWD) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules

module-debug:
@$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) V=1 CONFIG_AMNEZIAWG_DEBUG=y WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules
[ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko || true
@$(MAKE) -C $(KERNELDIR) M=$(PWD) V=1 CONFIG_AMNEZIAWG_DEBUG=y WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules

clean:
@$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
[ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && rm -rf $(TARGET_BUILD_DIR) || true

module-install:
@$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules_install
@$(MAKE) -C $(KERNELDIR) M=$(PWD) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules_install
$(DEPMOD) -b "$(DEPMODBASEDIR)" -a $(KERNELRELEASE)

install: module-install
Expand All @@ -122,7 +52,7 @@ check: clean
scan-build --html-title=wireguard-linux-compat -maxloop 100 --view --keep-going $(MAKE) module CONFIG_WIREGUARD_DEBUG=y C=2 CF="-D__CHECK_ENDIAN__"

coccicheck: clean
@$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) CONFIG_WIREGUARD_DEBUG=y coccicheck MODE=report
@$(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_WIREGUARD_DEBUG=y coccicheck MODE=report

cloc:
@cloc --skip-uniqueness --by-file --extract-with="$$(readlink -f ../kernel-tree-scripts/filter-compat-defines.sh) >FILE< > \$$(basename >FILE<)" $(filter-out wireguard.mod.c,$(wildcard *.c)) $(wildcard *.h)
Expand Down
13 changes: 8 additions & 5 deletions src/allowedips.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
#include "allowedips.h"
#include "peer.h"

enum { MAX_ALLOWEDIPS_DEPTH = 129 };

static struct kmem_cache *node_cache;

static void swap_endian(u8 *dst, const u8 *src, u8 bits)
{
if (bits == 32) {
*(u32 *)dst = be32_to_cpu(*(const __be32 *)src);
} else if (bits == 128) {
((u64 *)dst)[0] = be64_to_cpu(((const __be64 *)src)[0]);
((u64 *)dst)[1] = be64_to_cpu(((const __be64 *)src)[1]);
((u64 *)dst)[0] = get_unaligned_be64(src);
((u64 *)dst)[1] = get_unaligned_be64(src + 8);
}
}

Expand All @@ -40,7 +42,8 @@ static void push_rcu(struct allowedips_node **stack,
struct allowedips_node __rcu *p, unsigned int *len)
{
if (rcu_access_pointer(p)) {
WARN_ON(IS_ENABLED(DEBUG) && *len >= 128);
if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_DEPTH))
return;
stack[(*len)++] = rcu_dereference_raw(p);
}
}
Expand All @@ -52,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)

static void root_free_rcu(struct rcu_head *rcu)
{
struct allowedips_node *node, *stack[128] = {
struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = {
container_of(rcu, struct allowedips_node, rcu) };
unsigned int len = 1;

Expand All @@ -65,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)

static void root_remove_peer_lists(struct allowedips_node *root)
{
struct allowedips_node *node, *stack[128] = { root };
struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root };
unsigned int len = 1;

while (len > 0 && (node = stack[--len])) {
Expand Down
32 changes: 29 additions & 3 deletions src/compat/Kbuild.include
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#
# Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

ccflags-y += -include $(kbuild-dir)/compat/compat.h
asflags-y += -include $(kbuild-dir)/compat/compat-asm.h
LINUXINCLUDE := -DCOMPAT_VERSION=$(VERSION) -DCOMPAT_PATCHLEVEL=$(PATCHLEVEL) -DCOMPAT_SUBLEVEL=$(SUBLEVEL) -I$(kbuild-dir)/compat/version $(LINUXINCLUDE)
Expand Down Expand Up @@ -47,7 +45,7 @@ ccflags-y += -I$(kbuild-dir)/compat/udp_tunnel/include
amneziawg-y += compat/udp_tunnel/udp_tunnel.o
endif

ifeq ($(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/algapi.h"),)
ifeq ($(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/algapi.h")$(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/utils.h"),)
ccflags-y += -include $(kbuild-dir)/compat/memneq/include.h
amneziawg-y += compat/memneq/memneq.o
endif
Expand Down Expand Up @@ -109,3 +107,31 @@ endif
ifneq ($(shell grep -s -F "\#define LINUX_PACKAGE_ID \" Debian " "$(CURDIR)/include/generated/package.h"),)
ccflags-y += -DISDEBIAN
endif

ifeq ($(wildcard $(srctree)/include/crypto/blake2s.h),)
ccflags-y += -I$(kbuild-dir)/compat/crypto/blake2s/include
endif

ifeq ($(wildcard $(srctree)/include/crypto/chacha20poly1305.h),)
ccflags-y += -I$(kbuild-dir)/compat/crypto/chacha20poly1305/include
endif

ifeq ($(wildcard $(srctree)/include/crypto/utils.h),)
ccflags-y += -I$(kbuild-dir)/compat/crypto/utils/include
endif

ifeq ($(wildcard $(srctree)/include/crypto/curve25519.h),)
ccflags-y += -I$(kbuild-dir)/compat/crypto/curve25519/include
endif

ifeq ($(wildcard $(srctree)/include/linux/kstrtox.h),)
ccflags-y += -I$(kbuild-dir)/compat/kstrtox/include
endif

ifeq ($(wildcard $(srctree)/include/net/gso.h),)
ccflags-y += -I$(kbuild-dir)/compat/gso/include
endif

ifeq ($(wildcard $(srctree)/include/linux/sprintf.h),)
ccflags-y += -I$(kbuild-dir)/compat/sprintf/include
endif
91 changes: 84 additions & 7 deletions src/compat/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@
#error "WireGuard requires Linux >= 3.10"
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
#error "WireGuard has been merged into Linux >= 5.6 and therefore this compatibility module is no longer required."
#endif

#if defined(ISRHEL7)
#include <linux/skbuff.h>
#define headers_end headers_start
Expand Down Expand Up @@ -892,13 +888,14 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
#endif
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 200) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 249)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 285)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 320))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 200) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 249)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 285)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 320))) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
#define COMPAT_INIT_CRYPTO
#define blake2s_init zinc_blake2s_init
#define blake2s_init_key zinc_blake2s_init_key
#define blake2s_update zinc_blake2s_update
#define blake2s_final zinc_blake2s_final
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
#define blake2s_hmac zinc_blake2s_hmac
#define chacha20 zinc_chacha20
#define hchacha20 zinc_hchacha20
Expand Down Expand Up @@ -943,6 +940,13 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
#define chacha20_neon zinc_chacha20_neon
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
#define COMPAT_CRYPTO_IS_ZINC
#define COMPAT_MAYBE_SIMD_CONTEXT(ctx) , ctx
#else
#define COMPAT_MAYBE_SIMD_CONTEXT(ctx)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) && !defined(ISRHEL7)
#include <linux/skbuff.h>
static inline int skb_ensure_writable(struct sk_buff *skb, int write_len)
Expand Down Expand Up @@ -1121,7 +1125,7 @@ static const struct header_ops ip_tunnel_header_ops = { .parse_protocol = ip_tun
#endif
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 30)
#include <net/dst_cache.h>
struct dst_cache_pcpu {
unsigned long refresh_ts;
Expand Down Expand Up @@ -1196,4 +1200,77 @@ static inline void dst_cache_reset_now(struct dst_cache *dst_cache)
#define from_timer(var, callback_timer, timer_fieldname) container_of((struct timer_list *)callback_timer, typeof(*var), timer_fieldname)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
#include <net/flow.h>
#define flowi4_to_flowi_common(fl4) flowi4_to_flowi(fl4)
#define flowi6_to_flowi_common(fl4) flowi6_to_flowi(fl4)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
#define genl_info_dump(cb) genl_dumpit_info(cb)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 84) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 312) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 274) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 215) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 154) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
#define timer_delete_sync(timer) del_timer_sync(timer)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)
#include <linux/random.h>
static inline u32 get_random_u32_below(u32 ceil)
{
return get_random_u32() % ceil;
}
static inline u32 get_random_u32_inclusive(u32 floor, u32 ceil)
{
return floor + get_random_u32_below(ceil - floor + 1);
}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
#define COMPAT_NETIF_HAS_WEIGHT
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
#define COMPAT_GENL_HAS_RESV_START_OP
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 296) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 229) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 163) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) && \
!(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 86) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
#undef DEV_STATS_INC
#define DEV_STATS_INC(DEV, FIELD) ++DEV->stats.FIELD
#undef DEV_STATS_ADD
#define DEV_STATS_ADD(DEV, FIELD, VAL) DEV->stats.FIELD += VAL
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
#define COMPAT_SKB_HAS_SKB_START
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
#define dev_get_tstats64 ip_tunnel_get_stats64
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
#define COMPAT_NETDEV_HAS_LLTX_PARAM
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
static inline void dev_sw_netstats_rx_add(struct net_device *dev, unsigned int len) {
struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);

u64_stats_update_begin(&tstats->syncp);
++tstats->rx_packets;
tstats->rx_bytes += len;
u64_stats_update_end(&tstats->syncp);
put_cpu_ptr(tstats);
}
#endif

#endif /* _WG_COMPAT_H */
1 change: 1 addition & 0 deletions src/compat/crypto/blake2s/include/crypto/blake2s.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <zinc/blake2s.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <zinc/chacha20poly1305.h>
1 change: 1 addition & 0 deletions src/compat/crypto/curve25519/include/crypto/curve25519.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <zinc/curve25519.h>
1 change: 1 addition & 0 deletions src/compat/crypto/utils/include/crypto/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <crypto/algapi.h>
6 changes: 6 additions & 0 deletions src/compat/gso/include/net/gso.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _AWG_COMPAT_NET_GSO
#define _AWG_COMPAT_NET_GSO

#include <linux/netdevice.h>

#endif
1 change: 1 addition & 0 deletions src/compat/kstrtox/include/linux/kstrtox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <linux/kernel.h>
1 change: 1 addition & 0 deletions src/compat/sprintf/include/linux/sprintf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <linux/kernel.h>
Loading