mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 17:48:58 +00:00
3888fa7880
Rather than using the clunky, old, slower wireguard-linux-compat out of tree module, this commit does a patch-by-patch backport of upstream's wireguard to 5.4. This specific backport is in widespread use, being part of SUSE's enterprise kernel, Oracle's enterprise kernel, Google's Android kernel, Gentoo's distro kernel, and probably more I've forgotten about. It's definately the "more proper" way of adding wireguard to a kernel than the ugly compat.h hell of the wireguard-linux-compat repo. And most importantly for OpenWRT, it allows using the same module configuration code for 5.10 as for 5.4, with no need for bifurcation. These patches are from the backport tree which is maintained in the open here: https://git.zx2c4.com/wireguard-linux/log/?h=backport-5.4.y I'll be sending PRs to update this as needed. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
149 lines
4.4 KiB
Diff
149 lines
4.4 KiB
Diff
From 9793cc7357e8d70fed9cb350d2d39346328cc73b Mon Sep 17 00:00:00 2001
|
|
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
|
Date: Tue, 11 Feb 2020 20:47:05 +0100
|
|
Subject: [PATCH 071/124] icmp: introduce helper for nat'd source address in
|
|
network device context
|
|
|
|
commit 0b41713b606694257b90d61ba7e2712d8457648b upstream.
|
|
|
|
This introduces a helper function to be called only by network drivers
|
|
that wraps calls to icmp[v6]_send in a conntrack transformation, in case
|
|
NAT has been used. We don't want to pollute the non-driver path, though,
|
|
so we introduce this as a helper to be called by places that actually
|
|
make use of this, as suggested by Florian.
|
|
|
|
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
|
Cc: Florian Westphal <fw@strlen.de>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
|
---
|
|
include/linux/icmpv6.h | 10 ++++++++++
|
|
include/net/icmp.h | 6 ++++++
|
|
net/ipv4/icmp.c | 33 +++++++++++++++++++++++++++++++++
|
|
net/ipv6/ip6_icmp.c | 34 ++++++++++++++++++++++++++++++++++
|
|
4 files changed, 83 insertions(+)
|
|
|
|
--- a/include/linux/icmpv6.h
|
|
+++ b/include/linux/icmpv6.h
|
|
@@ -22,12 +22,22 @@ extern int inet6_unregister_icmp_sender(
|
|
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
|
|
unsigned int data_len);
|
|
|
|
+#if IS_ENABLED(CONFIG_NF_NAT)
|
|
+void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
|
|
+#else
|
|
+#define icmpv6_ndo_send icmpv6_send
|
|
+#endif
|
|
+
|
|
#else
|
|
|
|
static inline void icmpv6_send(struct sk_buff *skb,
|
|
u8 type, u8 code, __u32 info)
|
|
{
|
|
+}
|
|
|
|
+static inline void icmpv6_ndo_send(struct sk_buff *skb,
|
|
+ u8 type, u8 code, __u32 info)
|
|
+{
|
|
}
|
|
#endif
|
|
|
|
--- a/include/net/icmp.h
|
|
+++ b/include/net/icmp.h
|
|
@@ -43,6 +43,12 @@ static inline void icmp_send(struct sk_b
|
|
__icmp_send(skb_in, type, code, info, &IPCB(skb_in)->opt);
|
|
}
|
|
|
|
+#if IS_ENABLED(CONFIG_NF_NAT)
|
|
+void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info);
|
|
+#else
|
|
+#define icmp_ndo_send icmp_send
|
|
+#endif
|
|
+
|
|
int icmp_rcv(struct sk_buff *skb);
|
|
int icmp_err(struct sk_buff *skb, u32 info);
|
|
int icmp_init(void);
|
|
--- a/net/ipv4/icmp.c
|
|
+++ b/net/ipv4/icmp.c
|
|
@@ -750,6 +750,39 @@ out:;
|
|
}
|
|
EXPORT_SYMBOL(__icmp_send);
|
|
|
|
+#if IS_ENABLED(CONFIG_NF_NAT)
|
|
+#include <net/netfilter/nf_conntrack.h>
|
|
+void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
|
+{
|
|
+ struct sk_buff *cloned_skb = NULL;
|
|
+ enum ip_conntrack_info ctinfo;
|
|
+ struct nf_conn *ct;
|
|
+ __be32 orig_ip;
|
|
+
|
|
+ ct = nf_ct_get(skb_in, &ctinfo);
|
|
+ if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
|
+ icmp_send(skb_in, type, code, info);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (skb_shared(skb_in))
|
|
+ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
|
|
+
|
|
+ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
|
|
+ (skb_network_header(skb_in) + sizeof(struct iphdr)) >
|
|
+ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
|
|
+ skb_network_offset(skb_in) + sizeof(struct iphdr))))
|
|
+ goto out;
|
|
+
|
|
+ orig_ip = ip_hdr(skb_in)->saddr;
|
|
+ ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip;
|
|
+ icmp_send(skb_in, type, code, info);
|
|
+ ip_hdr(skb_in)->saddr = orig_ip;
|
|
+out:
|
|
+ consume_skb(cloned_skb);
|
|
+}
|
|
+EXPORT_SYMBOL(icmp_ndo_send);
|
|
+#endif
|
|
|
|
static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
|
|
{
|
|
--- a/net/ipv6/ip6_icmp.c
|
|
+++ b/net/ipv6/ip6_icmp.c
|
|
@@ -45,4 +45,38 @@ out:
|
|
rcu_read_unlock();
|
|
}
|
|
EXPORT_SYMBOL(icmpv6_send);
|
|
+
|
|
+#if IS_ENABLED(CONFIG_NF_NAT)
|
|
+#include <net/netfilter/nf_conntrack.h>
|
|
+void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
|
+{
|
|
+ struct sk_buff *cloned_skb = NULL;
|
|
+ enum ip_conntrack_info ctinfo;
|
|
+ struct in6_addr orig_ip;
|
|
+ struct nf_conn *ct;
|
|
+
|
|
+ ct = nf_ct_get(skb_in, &ctinfo);
|
|
+ if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
|
+ icmpv6_send(skb_in, type, code, info);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (skb_shared(skb_in))
|
|
+ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
|
|
+
|
|
+ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
|
|
+ (skb_network_header(skb_in) + sizeof(struct ipv6hdr)) >
|
|
+ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
|
|
+ skb_network_offset(skb_in) + sizeof(struct ipv6hdr))))
|
|
+ goto out;
|
|
+
|
|
+ orig_ip = ipv6_hdr(skb_in)->saddr;
|
|
+ ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
|
|
+ icmpv6_send(skb_in, type, code, info);
|
|
+ ipv6_hdr(skb_in)->saddr = orig_ip;
|
|
+out:
|
|
+ consume_skb(cloned_skb);
|
|
+}
|
|
+EXPORT_SYMBOL(icmpv6_ndo_send);
|
|
+#endif
|
|
#endif
|