From patchwork Sat Feb 27 06:40:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Shan Wei X-Patchwork-Id: 46425 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 58C1FB7D96 for ; Sat, 27 Feb 2010 17:40:31 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753806Ab0B0GkO (ORCPT ); Sat, 27 Feb 2010 01:40:14 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:50560 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1753650Ab0B0GkM convert rfc822-to-8bit (ORCPT ); Sat, 27 Feb 2010 01:40:12 -0500 Received: from tang.cn.fujitsu.com (tang.cn.fujitsu.com [10.167.250.3]) by song.cn.fujitsu.com (Postfix) with ESMTP id 27D9C170044; Sat, 27 Feb 2010 14:40:12 +0800 (CST) Received: from fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id o1R6dDi4007452; Sat, 27 Feb 2010 14:39:13 +0800 Received: from [10.167.141.214] (unknown [10.167.141.214]) by fnst.cn.fujitsu.com (Postfix) with ESMTPA id 6D3E7D4867; Sat, 27 Feb 2010 14:42:05 +0800 (CST) Message-ID: <4B88BE4C.3000504@cn.fujitsu.com> Date: Sat, 27 Feb 2010 14:40:12 +0800 From: Shan Wei User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 To: Patrick McHardy , David Miller , Alexey Dobriyan , Yasuyuki KOZAKAI , "netdev@vger.kernel.org" , netfilter-devel@vger.kernel.org Subject: [RFC PATCH net-next 6/7 v2]IPv6:netfilter: Record MIB counter after a fragment reached Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch records MIB counter about fragments reassembly after a fragment reached. Note: For the lack of memory, if fails to clone skb, pull skb or create fragment queue, then not to forward skb to IPv6 stack, and drop it, just like IPv4. v1->v2: 1. Conntrack can track a single fragment with MF=0,offset=0 now. (applied patch with title [nf_conntrack_reasm: properly handle packets fragmented into a single fragment]) So delete the changes when seeing a single fragment with MF=0,offset=0. Signed-off-by: Shan Wei --- net/ipv6/netfilter/nf_conntrack_reasm.c | 25 ++++++++++++++++++++----- 1 files changed, 20 insertions(+), 5 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 4640795..fc97a68 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -680,27 +680,31 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) u8 prevhdr; struct sk_buff *ret_skb = NULL; struct net *net = dev ? dev_net(dev) : dev_net(skb_dst(skb)->dev); + struct inet6_dev *idev; + idev = dev ? in6_dev_get(dev) : ip6_dst_idev(skb_dst(skb)); /* Jumbo payload inhibits frag. header */ if (ipv6_hdr(skb)->payload_len == 0) { pr_debug("payload len = 0\n"); - return skb; + goto out_nofrag; } if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0) - return skb; + goto out_nofrag; + + IP6_INC_STATS(net, idev, IPSTATS_MIB_REASMREQDS); clone = skb_clone(skb, GFP_ATOMIC); if (clone == NULL) { pr_debug("Can't clone skb\n"); - return skb; + goto out_drop_skb; } NFCT_FRAG6_CB(clone)->orig = skb; if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) { pr_debug("message is too short.\n"); - goto ret_orig; + goto out_drop_skb; } skb_set_transport_header(clone, fhoff); @@ -713,7 +717,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr); if (fq == NULL) { pr_debug("Can't find and can't create new queue\n"); - goto ret_orig; + goto out_drop_skb; } spin_lock(&fq->q.lock); @@ -732,13 +736,24 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) pr_debug("Can't reassemble fragmented packets\n"); } spin_unlock(&fq->q.lock); + if (dev && idev) + in6_dev_put(idev); fq_put(fq); return ret_skb; ret_orig: kfree_skb(clone); +out_nofrag: + if (dev && idev) + in6_dev_put(idev); return skb; +out_drop_skb: + IP6_INC_STATS(net, idev, IPSTATS_MIB_REASMFAILS); + kfree_skb(clone); + kfree_skb(skb); + skb = NULL; + goto out_nofrag; } void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,