From patchwork Tue Nov 15 09:01:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 694892 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3tJ1br4qQYz9t2D for ; Tue, 15 Nov 2016 20:01:59 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=verge.net.au header.i=@verge.net.au header.b="kFm3PyRd"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S941378AbcKOJB6 (ORCPT ); Tue, 15 Nov 2016 04:01:58 -0500 Received: from kirsty.vergenet.net ([202.4.237.240]:47527 "EHLO kirsty.vergenet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S937351AbcKOJB4 (ORCPT ); Tue, 15 Nov 2016 04:01:56 -0500 Received: from penelope.kanocho.kobe.vergenet.net (unknown [217.111.208.18]) by kirsty.vergenet.net (Postfix) with ESMTPSA id 7E32825BEC2; Tue, 15 Nov 2016 20:01:53 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=verge.net.au; s=mail; t=1479200513; bh=l2WHo2O3OEcbetU61ys9nVyPTWaHzWH0XINtrcb5HWY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kFm3PyRd9lpZkJWooAA5K7MpWYUDs5bvNto3kqpdiWwdpwPWob1CFIbIhnWGlJ3dg CvwhXtYgbMilbIhfrtAJMZKKq5Qk7SvpQpOSqigjE807A6vQv6bqeXE9eZTceep86w RpHVwtA/YzKUL/C9+67/G3PdQRSMLmqYGp0qJ5TE= Received: by penelope.kanocho.kobe.vergenet.net (Postfix, from userid 7100) id 1589B6077C; Tue, 15 Nov 2016 10:01:50 +0100 (CET) From: Simon Horman To: Pablo Neira Ayuso Cc: lvs-devel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, Wensong Zhang , Julian Anastasov , Dwip Banerjee , Simon Horman Subject: [PATCH nf-next 2/2] ipvs: Decrement ttl Date: Tue, 15 Nov 2016 10:01:43 +0100 Message-Id: <1479200503-25842-3-git-send-email-horms@verge.net.au> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1479200503-25842-1-git-send-email-horms@verge.net.au> References: <1479200503-25842-1-git-send-email-horms@verge.net.au> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Dwip Banerjee We decrement the IP ttl in all the modes in order to prevent infinite route loops. The changes were done based on Julian Anastasov's suggestions in a prior thread. The ttl based check/discard and the actual decrement are done in __ip_vs_get_out_rt() and in __ip_vs_get_out_rt_v6(), for the IPv6 case. decrement_ttl() implements the actual functionality for the two cases. Signed-off-by: Dwip Banerjee Acked-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_xmit.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 01d3d894de46..4e1a98fcc8c3 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -254,6 +254,54 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af, return true; } +static inline bool decrement_ttl(struct netns_ipvs *ipvs, + int skb_af, + struct sk_buff *skb) +{ + struct net *net = ipvs->net; + +#ifdef CONFIG_IP_VS_IPV6 + if (skb_af == AF_INET6) { + struct dst_entry *dst = skb_dst(skb); + + /* check and decrement ttl */ + if (ipv6_hdr(skb)->hop_limit <= 1) { + /* Force OUTPUT device used as source address */ + skb->dev = dst->dev; + icmpv6_send(skb, ICMPV6_TIME_EXCEED, + ICMPV6_EXC_HOPLIMIT, 0); + __IP6_INC_STATS(net, ip6_dst_idev(dst), + IPSTATS_MIB_INHDRERRORS); + + return false; + } + + /* don't propagate ttl change to cloned packets */ + if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) + return false; + + ipv6_hdr(skb)->hop_limit--; + } else +#endif + { + if (ip_hdr(skb)->ttl <= 1) { + /* Tell the sender its packet died... */ + __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS); + icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); + return false; + } + + /* don't propagate ttl change to cloned packets */ + if (!skb_make_writable(skb, sizeof(struct iphdr))) + return false; + + /* Decrease ttl */ + ip_decrease_ttl(ip_hdr(skb)); + } + + return true; +} + /* Get route to destination or remote server */ static int __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, @@ -326,6 +374,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, return local; } + if (!decrement_ttl(ipvs, skb_af, skb)) + goto err_put; + if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) { mtu = dst_mtu(&rt->dst); } else { @@ -473,6 +524,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, return local; } + if (!decrement_ttl(ipvs, skb_af, skb)) + goto err_put; + /* MTU checking */ if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) mtu = dst_mtu(&rt->dst);