diff mbox

IPVS: Add handling of incoming ICMPV6_PKT_TOOBIG messages

Message ID 20090724024711.GA13280@verge.net.au
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Simon Horman July 24, 2009, 2:47 a.m. UTC
From: Julius Volz <julius.volz@gmail.com>

IPVS: Add handling of incoming ICMPV6_PKT_TOOBIG messages

Add handling of incoming ICMPv6 Packet Too Big messages. This message
is received when a realserver sends a packet >PMTU to the client. The
hop on this path with insufficient MTU will generate an ICMPv6 Packet
Too Big message back to the VIP. The LVS server receives this message,
but the call to the function handling this has been missing. Thus, IPVS
fails to forward the message to the real server, which then does not
adjust the path MTU. This patch adds the missing call to
ip_vs_in_icmp_v6() in ip_vs_in() to handle this situation.

Thanks to Rob Gallagher from HEAnet for reporting this issue and for
testing this patch in production (with direct routing mode).

Signed-off-by: Julius Volz <julius.volz@gmail.com>
Tested-by: Rob Gallagher <robert.gallagher@heanet.ie>
Signed-off-by: Simon Horman <horms@verge.net.au>

---
 net/netfilter/ipvs/ip_vs_core.c |   23 +++++++++++++++++------
 1 files changed, 17 insertions(+), 6 deletions(-)

Dave, please consider applying this change.

I'm ok with it not going into 2.6.31 as I don't think that
many people are affected by this problem.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Eric Dumazet July 24, 2009, 4:25 a.m. UTC | #1
Simon Horman a écrit :
> From: Julius Volz <julius.volz@gmail.com>
> 
> IPVS: Add handling of incoming ICMPV6_PKT_TOOBIG messages
> 
> Add handling of incoming ICMPv6 Packet Too Big messages. This message
> is received when a realserver sends a packet >PMTU to the client. The
> hop on this path with insufficient MTU will generate an ICMPv6 Packet
> Too Big message back to the VIP. The LVS server receives this message,
> but the call to the function handling this has been missing. Thus, IPVS
> fails to forward the message to the real server, which then does not
> adjust the path MTU. This patch adds the missing call to
> ip_vs_in_icmp_v6() in ip_vs_in() to handle this situation.
> 
> Thanks to Rob Gallagher from HEAnet for reporting this issue and for
> testing this patch in production (with direct routing mode).
> 
> Signed-off-by: Julius Volz <julius.volz@gmail.com>
> Tested-by: Rob Gallagher <robert.gallagher@heanet.ie>
> Signed-off-by: Simon Horman <horms@verge.net.au>
> 
> ---
>  net/netfilter/ipvs/ip_vs_core.c |   23 +++++++++++++++++------
>  1 files changed, 17 insertions(+), 6 deletions(-)
> 
> Dave, please consider applying this change.
> 
> I'm ok with it not going into 2.6.31 as I don't think that
> many people are affected by this problem.
> 
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 8dddb17..5750800 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1274,13 +1274,24 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
>  		return NF_ACCEPT;
>  	}
>  
> -	if (unlikely(iph.protocol == IPPROTO_ICMP)) {
> -		int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
> +#ifdef CONFIG_IP_VS_IPV6
> +	if (af == AF_INET6) {
> +		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
> +			int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
>  
> -		if (related)
> -			return verdict;
> -		ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> -	}
> +			if (related)
> +				return verdict;
> +			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> +		}
> +	} else
> +#endif
> +		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
> +			int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
> +
> +			if (related)
> +				return verdict;
> +			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> +		}
>  
>  	/* Protocol supported? */
>  	pp = ip_vs_proto_get(iph.protocol);

I see no reference to ICMPV6_PKT_TOOBIG in this patch, so ChangeLog might be
misleading or uncomplete, since other ICMPV6 message types 
(ICMPV6_DEST_UNREACH/ICMPV6_TIME_EXCEED) will also be forwarded/handled ?


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller July 27, 2009, 2:19 a.m. UTC | #2
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 24 Jul 2009 06:25:25 +0200

> I see no reference to ICMPV6_PKT_TOOBIG in this patch, so ChangeLog might be
> misleading or uncomplete, since other ICMPV6 message types 
> (ICMPV6_DEST_UNREACH/ICMPV6_TIME_EXCEED) will also be forwarded/handled ?

Agreed, this commit message could use a tidy.  What the patch
actually is doing is adding the handling of ipv6 icmp messages
at all.

Simon could you clarify the commit message a bit and resubmit?

Thanks!
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Simon Horman July 27, 2009, 2:37 a.m. UTC | #3
On Sun, Jul 26, 2009 at 07:19:05PM -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Fri, 24 Jul 2009 06:25:25 +0200
> 
> > I see no reference to ICMPV6_PKT_TOOBIG in this patch, so ChangeLog
> > might be misleading or uncomplete, since other ICMPV6 message types
> > (ICMPV6_DEST_UNREACH/ICMPV6_TIME_EXCEED) will also be forwarded/handled
> > ?
> 
> Agreed, this commit message could use a tidy.  What the patch actually is
> doing is adding the handling of ipv6 icmp messages at all.
> 
> Simon could you clarify the commit message a bit and resubmit?

Will do.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Julius Volz July 27, 2009, 10:19 a.m. UTC | #4
On Mon, Jul 27, 2009 at 4:37 AM, Simon Horman<horms@verge.net.au> wrote:
> On Sun, Jul 26, 2009 at 07:19:05PM -0700, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Fri, 24 Jul 2009 06:25:25 +0200
>>
>> > I see no reference to ICMPV6_PKT_TOOBIG in this patch, so ChangeLog
>> > might be misleading or uncomplete, since other ICMPV6 message types
>> > (ICMPV6_DEST_UNREACH/ICMPV6_TIME_EXCEED) will also be forwarded/handled
>> > ?
>>
>> Agreed, this commit message could use a tidy.  What the patch actually is
>> doing is adding the handling of ipv6 icmp messages at all.
>>
>> Simon could you clarify the commit message a bit and resubmit?
>
> Will do.

Oops, yes. For some weird reason, only the specific problem that
caused the patch was in my head when writing that commit message. Feel
free to edit it to include ICMPv6 handling for in-out packets in
general.

Julius
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 8dddb17..5750800 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1274,13 +1274,24 @@  ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 		return NF_ACCEPT;
 	}
 
-	if (unlikely(iph.protocol == IPPROTO_ICMP)) {
-		int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
+#ifdef CONFIG_IP_VS_IPV6
+	if (af == AF_INET6) {
+		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
+			int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
 
-		if (related)
-			return verdict;
-		ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
-	}
+			if (related)
+				return verdict;
+			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+		}
+	} else
+#endif
+		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
+			int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
+
+			if (related)
+				return verdict;
+			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+		}
 
 	/* Protocol supported? */
 	pp = ip_vs_proto_get(iph.protocol);