Skip to content

Commit

Permalink
drivers: net: Modify WireGuard for backward compat
Browse files Browse the repository at this point in the history
Change-Id: I1c8e130a514a7b0329f8df8099cc84f4cc8d5822
Signed-off-by: Ratoriku <[email protected]>
  • Loading branch information
bgcngm authored and D3nesyan committed Aug 21, 2021
1 parent 837de68 commit b5a6060
Show file tree
Hide file tree
Showing 77 changed files with 43,318 additions and 73 deletions.
18 changes: 5 additions & 13 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,13 @@ config WIREGUARD
select NET_UDP_TUNNEL
select DST_CACHE
select CRYPTO
select CRYPTO_LIB_CURVE25519
select CRYPTO_LIB_CHACHA20POLY1305
select CRYPTO_LIB_BLAKE2S
select CRYPTO_CHACHA20_X86_64 if X86 && 64BIT
select CRYPTO_POLY1305_X86_64 if X86 && 64BIT
select CRYPTO_BLAKE2S_X86 if X86 && 64BIT
select CRYPTO_CURVE25519_X86 if X86 && 64BIT
select CRYPTO_ALGAPI
select ARM_CRYPTO if ARM
select ARM64_CRYPTO if ARM64
select CRYPTO_CHACHA20_NEON if (ARM || ARM64) && KERNEL_MODE_NEON
select CRYPTO_POLY1305_NEON if ARM64 && KERNEL_MODE_NEON
select CRYPTO_POLY1305_ARM if ARM
select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON
select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2
select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
select VFP
select VFPv3 if CPU_V7
select NEON if CPU_V7
select KERNEL_MODE_NEON if CPU_V7
help
WireGuard is a secure, fast, and easy to use replacement for IPSec
that uses modern cryptography and clever networking tricks. It's
Expand Down
13 changes: 12 additions & 1 deletion drivers/net/wireguard/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved.

ccflags-y := -O3
ccflags-y += -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt'
ccflags-$(CONFIG_WIREGUARD_DEBUG) += -DDEBUG
Expand All @@ -15,4 +19,11 @@ wireguard-y += allowedips.o
wireguard-y += ratelimiter.o
wireguard-y += cookie.o
wireguard-y += netlink.o
obj-$(CONFIG_WIREGUARD) := wireguard.o

ccflags-y += -Wframe-larger-than=2048
ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"'

include $(src)/crypto/Makefile.include
include $(src)/compat/Makefile.include

obj-$(if $(KBUILD_EXTMOD),m,$(CONFIG_WIREGUARD)) := wireguard.o
102 changes: 102 additions & 0 deletions drivers/net/wireguard/compat/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. 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

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

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

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

ifeq ($(wildcard $(srctree)/arch/x86/include/asm/intel-family.h)$(CONFIG_X86),y)
ccflags-y += -I$(kbuild-dir)/compat/intel-family-x86/include
endif

ifeq ($(wildcard $(srctree)/arch/x86/include/asm/fpu/api.h)$(CONFIG_X86),y)
ccflags-y += -I$(kbuild-dir)/compat/fpu-x86/include
endif

ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/simd.h)$(shell grep -s -F "generic-y += simd.h" "$(srctree)/arch/$(SRCARCH)/Makefile" "$(srctree)/arch/$(SRCARCH)/Makefile"),)
ccflags-y += -I$(kbuild-dir)/compat/simd-asm/include
endif

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

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

ifeq ($(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/algapi.h"),)
ccflags-y += -include $(kbuild-dir)/compat/memneq/include.h
wireguard-y += compat/memneq/memneq.o
endif

ifeq ($(shell grep -s -F "addr_gen_mode" "$(srctree)/include/linux/ipv6.h"),)
ccflags-y += -DCOMPAT_CANNOT_USE_DEV_CNF
endif

ifdef CONFIG_HZ
ifeq ($(wildcard $(CURDIR)/include/generated/timeconst.h),)
ccflags-y += $(shell bash -c '((a=$(CONFIG_HZ), b=1000000)); while ((b > 0)); do ((t=b, b=a%b, a=t)); done; echo "-DHZ_TO_USEC_NUM=$$((1000000/a)) -DHZ_TO_USEC_DEN=$$(($(CONFIG_HZ)/a))";')
endif
endif

ifeq ($(wildcard $(srctree)/arch/arm/include/asm/neon.h)$(CONFIG_ARM),y)
ccflags-y += -I$(kbuild-dir)/compat/neon-arm/include
endif
ifeq ($(wildcard $(srctree)/arch/arm64/include/asm/neon.h)$(CONFIG_ARM64),y)
ccflags-y += -I$(kbuild-dir)/compat/neon-arm/include
endif

ifeq ($(CONFIG_X86_64),y)
ifeq ($(ssse3_instr),)
ssse3_instr := $(call as-instr,pshufb %xmm0$(comma)%xmm0,-DCONFIG_AS_SSSE3=1)
ccflags-y += $(ssse3_instr)
asflags-y += $(ssse3_instr)
endif
ifeq ($(avx_instr),)
avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1)
ccflags-y += $(avx_instr)
asflags-y += $(avx_instr)
endif
ifeq ($(avx2_instr),)
avx2_instr := $(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1)
ccflags-y += $(avx2_instr)
asflags-y += $(avx2_instr)
endif
ifeq ($(avx512_instr),)
avx512_instr := $(call as-instr,vpmovm2b %k1$(comma)%zmm5,-DCONFIG_AS_AVX512=1)
ccflags-y += $(avx512_instr)
asflags-y += $(avx512_instr)
endif
ifeq ($(bmi2_instr),)
bmi2_instr :=$(call as-instr,mulx %rax$(comma)%rax$(comma)%rax,-DCONFIG_AS_BMI2=1)
ccflags-y += $(bmi2_instr)
asflags-y += $(bmi2_instr)
endif
ifeq ($(adx_instr),)
adx_instr :=$(call as-instr,adcx %rax$(comma)%rax,-DCONFIG_AS_ADX=1)
ccflags-y += $(adx_instr)
asflags-y += $(adx_instr)
endif
endif

ifneq ($(shell grep -s -F "\#define LINUX_PACKAGE_ID \" Debian " "$(CURDIR)/include/generated/package.h"),)
ccflags-y += -DISDEBIAN
endif
208 changes: 208 additions & 0 deletions drivers/net/wireguard/compat/checksum/checksum_partial_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
*/

#include <net/route.h>
#include <net/esp.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/ip6_checksum.h>

#define IP6_MF 0x0001
#define IP6_OFFSET 0xFFF8
static inline int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len, unsigned int max)
{
if (skb_headlen(skb) >= len)
return 0;
if (max > skb->len)
max = skb->len;
if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL)
return -ENOMEM;
if (skb_headlen(skb) < len)
return -EPROTO;
return 0;
}
#define MAX_IP_HDR_LEN 128
static inline int skb_checksum_setup_ip(struct sk_buff *skb, bool recalculate)
{
unsigned int off;
bool fragment;
int err;
fragment = false;
err = skb_maybe_pull_tail(skb, sizeof(struct iphdr), MAX_IP_HDR_LEN);
if (err < 0)
goto out;
if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF))
fragment = true;
off = ip_hdrlen(skb);
err = -EPROTO;
if (fragment)
goto out;
switch (ip_hdr(skb)->protocol) {
case IPPROTO_TCP:
err = skb_maybe_pull_tail(skb,
off + sizeof(struct tcphdr),
MAX_IP_HDR_LEN);
if (err < 0)
goto out;

if (!skb_partial_csum_set(skb, off,
offsetof(struct tcphdr, check))) {
err = -EPROTO;
goto out;
}

if (recalculate)
tcp_hdr(skb)->check =
~csum_tcpudp_magic(ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr,
skb->len - off,
IPPROTO_TCP, 0);
break;
case IPPROTO_UDP:
err = skb_maybe_pull_tail(skb,
off + sizeof(struct udphdr),
MAX_IP_HDR_LEN);
if (err < 0)
goto out;

if (!skb_partial_csum_set(skb, off,
offsetof(struct udphdr, check))) {
err = -EPROTO;
goto out;
}

if (recalculate)
udp_hdr(skb)->check =
~csum_tcpudp_magic(ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr,
skb->len - off,
IPPROTO_UDP, 0);
break;
default:
goto out;
}
err = 0;
out:
return err;
}
#define MAX_IPV6_HDR_LEN 256
#define OPT_HDR(type, skb, off) \
(type *)(skb_network_header(skb) + (off))
static inline int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
{
int err;
u8 nexthdr;
unsigned int off;
unsigned int len;
bool fragment;
bool done;
fragment = false;
done = false;
off = sizeof(struct ipv6hdr);
err = skb_maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN);
if (err < 0)
goto out;
nexthdr = ipv6_hdr(skb)->nexthdr;
len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
while (off <= len && !done) {
switch (nexthdr) {
case IPPROTO_DSTOPTS:
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING: {
struct ipv6_opt_hdr *hp;

err = skb_maybe_pull_tail(skb, off + sizeof(struct ipv6_opt_hdr), MAX_IPV6_HDR_LEN);
if (err < 0)
goto out;
hp = OPT_HDR(struct ipv6_opt_hdr, skb, off);
nexthdr = hp->nexthdr;
off += ipv6_optlen(hp);
break;
}
case IPPROTO_FRAGMENT: {
struct frag_hdr *hp;
err = skb_maybe_pull_tail(skb, off + sizeof(struct frag_hdr), MAX_IPV6_HDR_LEN);
if (err < 0)
goto out;
hp = OPT_HDR(struct frag_hdr, skb, off);
if (hp->frag_off & htons(IP6_OFFSET | IP6_MF))
fragment = true;
nexthdr = hp->nexthdr;
off += sizeof(struct frag_hdr);
break;
}
default:
done = true;
break;
}
}
err = -EPROTO;
if (!done || fragment)
goto out;
switch (nexthdr) {
case IPPROTO_TCP:
err = skb_maybe_pull_tail(skb,
off + sizeof(struct tcphdr),
MAX_IPV6_HDR_LEN);
if (err < 0)
goto out;

if (!skb_partial_csum_set(skb, off,
offsetof(struct tcphdr, check))) {
err = -EPROTO;
goto out;
}

if (recalculate)
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr,
skb->len - off,
IPPROTO_TCP, 0);
break;
case IPPROTO_UDP:
err = skb_maybe_pull_tail(skb,
off + sizeof(struct udphdr),
MAX_IPV6_HDR_LEN);
if (err < 0)
goto out;

if (!skb_partial_csum_set(skb, off,
offsetof(struct udphdr, check))) {
err = -EPROTO;
goto out;
}

if (recalculate)
udp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr,
skb->len - off,
IPPROTO_UDP, 0);
break;
default:
goto out;
}
err = 0;
out:
return err;
}
static inline int skb_checksum_setup(struct sk_buff *skb, bool recalculate)
{
int err;
switch (skb->protocol) {
case htons(ETH_P_IP):
err = skb_checksum_setup_ip(skb, recalculate);
break;

case htons(ETH_P_IPV6):
err = skb_checksum_setup_ipv6(skb, recalculate);
break;
default:
err = -EPROTO;
break;
}
return err;
}
Loading

0 comments on commit b5a6060

Please sign in to comment.