From patchwork Tue Aug 28 14:22:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesper Dangaard Brouer X-Patchwork-Id: 180501 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 075462C0261 for ; Wed, 29 Aug 2012 00:20:16 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752538Ab2H1OUI (ORCPT ); Tue, 28 Aug 2012 10:20:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:65136 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752269Ab2H1OUG (ORCPT ); Tue, 28 Aug 2012 10:20:06 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q7SEJj2h006365 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 28 Aug 2012 10:19:45 -0400 Received: from dragon.localdomain (ovpn-116-72.ams2.redhat.com [10.36.116.72]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q7SEJib8015583; Tue, 28 Aug 2012 10:19:44 -0400 Received: from [127.0.0.1] (localhost [IPv6:::1]) by dragon.localdomain (Postfix) with ESMTP id A86012C16FC; Tue, 28 Aug 2012 16:22:43 +0200 (CEST) From: Jesper Dangaard Brouer Subject: [PATCH V2 1/2] ipvs: IPv6 MTU checking cleanup and bugfix To: netdev@vger.kernel.org, "Patrick McHardy" , lvs-devel@vger.kernel.org, Julian Anastasov , Simon Horman , Pablo Neira Ayuso Cc: Jesper Dangaard Brouer , Hans Schillstrom , Wensong Zhang , netfilter-devel@vger.kernel.org Date: Tue, 28 Aug 2012 16:22:43 +0200 Message-ID: <20120828142122.11475.71918.stgit@dragon> In-Reply-To: <20120828142051.11475.63775.stgit@dragon> References: <20120828142051.11475.63775.stgit@dragon> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Cleaning up the IPv6 MTU checking in the IPVS xmit code, by using a common helper function __mtu_check_toobig_v6(). The MTU check for tunnel mode can also use this helper as ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) is qual to skb->len. And the 'mtu' variable have been adjusted before calling helper. Notice, this also fixes a bug, as the the MTU check in ip_vs_dr_xmit_v6() were missing a check for skb_is_gso(). This bug e.g. caused issues for KVM IPVS setups, where different Segmentation Offloading techniques are utilized, between guests, via the virtio driver. This resulted in very bad performance, due to the ICMPv6 "too big" messages didn't affect the sender. Signed-off-by: Jesper Dangaard Brouer --- In V2: we also make tunnel mode use the common helper net/netfilter/ipvs/ip_vs_xmit.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-) -- 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 --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 543a554..67a3978 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -85,6 +85,15 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) return dst; } +static inline bool +__mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu) +{ + if (skb->len > mtu && !skb_is_gso(skb)) { + return true; /* Packet size violate MTU size */ + } + return false; +} + /* Get route to daddr, update *saddr, optionally bind route to saddr */ static struct rtable *do_output_route4(struct net *net, __be32 daddr, u32 rtos, int rt_mode, __be32 *saddr) @@ -491,7 +500,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); - if (skb->len > mtu && !skb_is_gso(skb)) { + if (__mtu_check_toobig_v6(skb, mtu)) { if (!skb->dev) { struct net *net = dev_net(skb_dst(skb)->dev); @@ -712,7 +721,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); - if (skb->len > mtu && !skb_is_gso(skb)) { + if (__mtu_check_toobig_v6(skb, mtu)) { if (!skb->dev) { struct net *net = dev_net(skb_dst(skb)->dev); @@ -946,8 +955,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); - if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) && - !skb_is_gso(skb)) { + /* MTU checking: Notice that 'mtu' have been adjusted before hand */ + if (__mtu_check_toobig_v6(skb, mtu)) { if (!skb->dev) { struct net *net = dev_net(skb_dst(skb)->dev); @@ -1113,7 +1122,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); - if (skb->len > mtu) { + if (__mtu_check_toobig_v6(skb, mtu)) { if (!skb->dev) { struct net *net = dev_net(skb_dst(skb)->dev); @@ -1349,7 +1358,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); - if (skb->len > mtu && !skb_is_gso(skb)) { + if (__mtu_check_toobig_v6(skb, mtu)) { if (!skb->dev) { struct net *net = dev_net(skb_dst(skb)->dev);