From patchwork Tue Apr 19 13:37:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Edward Cree X-Patchwork-Id: 612144 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 3qq5fq50h8z9t90 for ; Tue, 19 Apr 2016 23:37:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754216AbcDSNhi (ORCPT ); Tue, 19 Apr 2016 09:37:38 -0400 Received: from nbfkord-smmo02.seg.att.com ([209.65.160.78]:48661 "EHLO nbfkord-smmo02.seg.att.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752887AbcDSNhh (ORCPT ); Tue, 19 Apr 2016 09:37:37 -0400 Received: from unknown [193.34.186.16] (EHLO webmail.solarflare.com) by nbfkord-smmo02.seg.att.com(mxl_mta-7.2.4-7) over TLS secured channel with ESMTP id f9436175.0.2092786.00-2350.5096750.nbfkord-smmo02.seg.att.com (envelope-from ); Tue, 19 Apr 2016 13:37:36 +0000 (UTC) X-MXL-Hash: 571634a02a35c770-96a1a0395da60e197b7803b182842e41df80e7c3 Received: from ec-desktop.uk.level5networks.com (10.17.20.45) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id 15.0.1044.25; Tue, 19 Apr 2016 14:37:30 +0100 From: Edward Cree Subject: [RFC PATCH net-next 8/8] net: ipv4: listify ip_rcv_finish To: , David Miller References: <5716338E.4050003@solarflare.com> CC: Jesper Dangaard Brouer , Message-ID: <57163498.50705@solarflare.com> Date: Tue, 19 Apr 2016 14:37:28 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 In-Reply-To: <5716338E.4050003@solarflare.com> X-Originating-IP: [10.17.20.45] X-ClientProxiedBy: ocex03.SolarFlarecom.com (10.20.40.36) To ukex01.SolarFlarecom.com (10.17.10.4) X-TM-AS-Product-Ver: SMEX-11.0.0.1191-8.000.1202-22270.003 X-TM-AS-Result: No--4.736000-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-AnalysisOut: [v=2.1 cv=OMMhqHuB c=1 sm=1 tr=0 a=8P+NB+fYZDP74ap4g4d9Kw==] X-AnalysisOut: [:17 a=fVG4DLb5TBsA:10 a=IkcTkHD0fZMA:10 a=kziv93cY1bsA:10 ] X-AnalysisOut: [a=zRKbQ67AAAAA:8 a=_1by0SLh4r5x_QYKSAkA:9 a=QEXdDO2ut3YA:1] X-AnalysisOut: [0] X-Spam: [F=0.2000000000; CM=0.500; S=0.200(2015072901)] X-MAIL-FROM: X-SOURCE-IP: [193.34.186.16] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Edward Cree --- net/ipv4/ip_input.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index e7d0d85..5bbc409 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -308,7 +308,8 @@ drop: return true; } -static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +static int ip_rcv_finish_core(struct net *net, struct sock *sk, + struct sk_buff *skb) { const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; @@ -385,13 +386,22 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) goto drop; } - return dst_input(skb); + return NET_RX_SUCCESS; drop: kfree_skb(skb); return NET_RX_DROP; } +static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +{ + int ret = ip_rcv_finish_core(net, sk, skb); + + if (ret != NET_RX_DROP) + ret = dst_input(skb); + return ret; +} + /* * Main IP Receive routine. */ @@ -501,16 +511,54 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, ip_rcv_finish); } +static void ip_sublist_rcv_finish(struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(list)) != NULL) + dst_input(skb); +} + +static void ip_list_rcv_finish(struct net *net, struct sock *sk, + struct sk_buff_head *list) +{ + struct dst_entry *curr_dst = NULL; + struct sk_buff_head sublist; + struct sk_buff *skb; + + __skb_queue_head_init(&sublist); + + while ((skb = __skb_dequeue(list)) != NULL) { + struct dst_entry *dst; + + if (ip_rcv_finish_core(net, sk, skb) == NET_RX_DROP) + continue; + + dst = skb_dst(skb); + if (skb_queue_empty(&sublist)) { + curr_dst = dst; + } else if (curr_dst != dst) { + /* dispatch old sublist */ + ip_sublist_rcv_finish(&sublist); + /* start new sublist */ + __skb_queue_head_init(&sublist); + curr_dst = dst; + } + /* add to current sublist */ + __skb_queue_tail(&sublist, skb); + } + /* dispatch final sublist */ + ip_sublist_rcv_finish(&sublist); +} + static void ip_sublist_rcv(struct sk_buff_head *list, struct net_device *dev, struct net *net) { struct sk_buff_head sublist; - struct sk_buff *skb; NF_HOOK_LIST(NFPROTO_IPV4, NF_INET_PRE_ROUTING, net, NULL, list, &sublist, dev, NULL, ip_rcv_finish); - while ((skb = __skb_dequeue(&sublist)) != NULL) - ip_rcv_finish(net, NULL, skb); + ip_list_rcv_finish(net, NULL, &sublist); } /* Receive a list of IP packets */