From 8644e1cddac2df86a67e3a407629d8416f8a3c5e Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 24 Jun 2017 04:27:30 +0200 Subject: device: remove icmp conntrack hacks This logic belongs upstream. Signed-off-by: Jason A. Donenfeld --- src/compat/compat.h | 31 +++++++++++++++++++++++++++++++ src/device.c | 39 ++++++--------------------------------- src/tests/debug.mk | 2 -- 3 files changed, 37 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/compat/compat.h b/src/compat/compat.h index eb17c8e..159abb1 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -284,6 +284,37 @@ static inline u64 ktime_get_ns(void) #define inet_confirm_addr(a,b,c,d,e) inet_confirm_addr(b,c,d,e) #endif +/* https://lkml.org/lkml/2017/6/23/790 */ +#if IS_ENABLED(CONFIG_NF_CONNTRACK) +#include +#include +#include +#include +#include +static inline void new_icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb_in, &ctinfo); + if (skb_network_header(skb_in) < skb_in->head || (skb_network_header(skb_in) + sizeof(struct iphdr)) > skb_tail_pointer(skb_in)) + return; + if (ct) + ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip; + icmp_send(skb_in, type, code, info); +} +static inline void new_icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + if (skb_network_header(skb) < skb->head || (skb_network_header(skb) + sizeof(struct ipv6hdr)) > skb_tail_pointer(skb)) + return; + if (ct) + ipv6_hdr(skb)->saddr = ct->tuplehash[0].tuple.src.u3.in6; + icmpv6_send(skb, type, code, info); +} +#define icmp_send(a,b,c,d) new_icmp_send(a,b,c,d) +#define icmpv6_send(a,b,c,d) new_icmpv6_send(a,b,c,d) +#endif + /* https://lkml.org/lkml/2015/6/12/415 */ #include static inline struct net_device *netdev_pub(void *dev) diff --git a/src/device.c b/src/device.c index 1b7e151..22632e5 100644 --- a/src/device.c +++ b/src/device.c @@ -22,10 +22,6 @@ #include #include #include -#if IS_ENABLED(CONFIG_NF_CONNTRACK) -#include -#include -#endif static LIST_HEAD(device_list); @@ -110,34 +106,6 @@ static int stop(struct net_device *dev) return 0; } -static void skb_unsendable(struct sk_buff *skb, struct net_device *dev) -{ -#if IS_ENABLED(CONFIG_NF_CONNTRACK) - /* This conntrack stuff is because the rate limiting needs to be applied - * to the original src IP, so we have to restore saddr in the IP header. - * It's not needed if conntracking isn't in the kernel, because in that - * case the saddr wouldn't be NAT-transformed anyway. */ - enum ip_conntrack_info ctinfo; - struct nf_conn *ct = nf_ct_get(skb, &ctinfo); -#endif - ++dev->stats.tx_errors; - - if (skb->len >= sizeof(struct iphdr) && ip_hdr(skb)->version == 4) { -#if IS_ENABLED(CONFIG_NF_CONNTRACK) - if (ct) - ip_hdr(skb)->saddr = ct->tuplehash[0].tuple.src.u3.ip; -#endif - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); - } else if (skb->len >= sizeof(struct ipv6hdr) && ip_hdr(skb)->version == 6) { -#if IS_ENABLED(CONFIG_NF_CONNTRACK) - if (ct) - ipv6_hdr(skb)->saddr = ct->tuplehash[0].tuple.src.u3.in6; -#endif - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); - } - kfree_skb(skb); -} - static netdev_tx_t xmit(struct sk_buff *skb, struct net_device *dev) { struct wireguard_device *wg = netdev_priv(dev); @@ -205,7 +173,12 @@ static netdev_tx_t xmit(struct sk_buff *skb, struct net_device *dev) err_peer: peer_put(peer); err: - skb_unsendable(skb, dev); + ++dev->stats.tx_errors; + if (skb->protocol == htons(ETH_P_IP)) + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); + else if (skb->protocol == htons(ETH_P_IPV6)) + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); + kfree_skb(skb); return ret; } diff --git a/src/tests/debug.mk b/src/tests/debug.mk index 5078a87..5da3280 100644 --- a/src/tests/debug.mk +++ b/src/tests/debug.mk @@ -19,8 +19,6 @@ test: debug -sudo modprobe ip6_udp_tunnel -sudo modprobe udp_tunnel -sudo modprobe ipv6 - -sudo modprobe nf_conntrack_ipv4 - -sudo modprobe nf_conntrack_ipv6 -sudo rmmod wireguard -sudo insmod wireguard.ko sudo PATH="$(shell pwd)/tools:$$PATH:/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" ./tests/netns.sh -- cgit v1.2.3