From patchwork Wed Jul 16 03:28:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Held X-Patchwork-Id: 370584 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 48C171400AF for ; Wed, 16 Jul 2014 13:28:42 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760943AbaGPD2i (ORCPT ); Tue, 15 Jul 2014 23:28:38 -0400 Received: from mail-qc0-f201.google.com ([209.85.216.201]:62446 "EHLO mail-qc0-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759199AbaGPD2h (ORCPT ); Tue, 15 Jul 2014 23:28:37 -0400 Received: by mail-qc0-f201.google.com with SMTP id m20so50174qcx.4 for ; Tue, 15 Jul 2014 20:28:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dJgB1qk40R2Rb3Jyx1rN+xLPO5XnQIwaVKJUwVMTQE8=; b=VgBypBA6RbfwN+MapaP4tD/ujl/I7asqfPXEY/R8aZWD8Jbt2NugnMjm5kBwcIDapb aYXTZ8dQhC28F6KRRaeSIty5TymDN8n/8rffFrOND4qsPJX1dsc6RNWHwTTpQqWAtudO hPtYZyEELBYB4JReEdVAhn1pWxKn3pcyb8kQDCXTylhg3tJMJRsL7tffEZd1km6lTyIh aXht+OMr/hExKmQwvKGAYRzlP1EOL5v5oDO83BmfL05uWYD+sX2Ziorm30q2nQMuCa8Y CBqgY9lrwmq2I3YD+HqJmNrsWW8jkoC4xpF67yYpsvVZJHiGI3fr2VDCMI3to2oN/XeW d5gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dJgB1qk40R2Rb3Jyx1rN+xLPO5XnQIwaVKJUwVMTQE8=; b=P/HW098/cyw6lpZL29qlccBZKrOuZ8WYZl5uyhEAUDlNr6g5nQsNcvYZF2I/7swPof 0Uqb3bE80vAMhKMp8M5EzqgnGeg9xSHe6C3Q4jXdE+UD2HOJYLCozEgWTzu1Uar9fJ3a pyGWKrGBIlRC7xEMkWFn40gAMxeymOldz6t3LBUpWwU+0FAYdD0s8WiRSjXay72g5YGE Ex/Yj+Xv1n0r3HhIaYQJ/bZAhH1Smdhkt/w8vwqmGkTjfaJn0lZF92/6+G01Dr8qOhPw 1gQS7U8xw8ROPkfiH9yuekRvoHSQlGyQciZ5AtSCIs+6PU4aH+pJFT3W5blNntbNKSz7 ZmsA== X-Gm-Message-State: ALoCoQnBvVLsTxGm25qaQ/gYqA3QLLS0rRXsvQLS2SCKvQfltWX1qu7H6hsiQjRjs0/T06+UTJNa X-Received: by 10.236.47.163 with SMTP id t23mr11508058yhb.41.1405481316093; Tue, 15 Jul 2014 20:28:36 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id j43si1091960yhh.5.2014.07.15.20.28.36 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 15 Jul 2014 20:28:36 -0700 (PDT) Received: from fork.nyc.corp.google.com (fork.nyc.corp.google.com [172.26.26.60]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id DD7B331C32B; Tue, 15 Jul 2014 20:28:35 -0700 (PDT) Received: by fork.nyc.corp.google.com (Postfix, from userid 10076) id 75D5BA14AE; Tue, 15 Jul 2014 23:28:35 -0400 (EDT) From: David Held To: netdev@vger.kernel.org Cc: davem@davemloft.net, eric.dumazet@gmail.com, willemb@google.com, David Held Subject: [PATCH net-next v3 1/2] udp: Simplify __udp*_lib_mcast_deliver. Date: Tue, 15 Jul 2014 23:28:31 -0400 Message-Id: <1405481312-7790-2-git-send-email-drheld@google.com> X-Mailer: git-send-email 2.0.0.526.g5318336 In-Reply-To: <1405481312-7790-1-git-send-email-drheld@google.com> References: <1405481312-7790-1-git-send-email-drheld@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Switch to using sk_nulls_for_each which shortens the code and makes it easier to update. Signed-off-by: David Held Acked-by: Eric Dumazet --- net/ipv4/udp.c | 48 ++++++++++---------------------- net/ipv6/udp.c | 88 +++++++++++++++++++++++----------------------------------- 2 files changed, 49 insertions(+), 87 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f6dfe52..1347a24 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -594,26 +594,6 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk, return true; } -static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk, - __be16 loc_port, __be32 loc_addr, - __be16 rmt_port, __be32 rmt_addr, - int dif) -{ - struct hlist_nulls_node *node; - unsigned short hnum = ntohs(loc_port); - - sk_nulls_for_each_from(sk, node) { - if (__udp_is_mcast_sock(net, sk, - loc_port, loc_addr, - rmt_port, rmt_addr, - dif, hnum)) - goto found; - } - sk = NULL; -found: - return sk; -} - /* * This routine is called by the ICMP module when it gets some * sort of error condition. If err < 0 then the socket should @@ -1664,23 +1644,23 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, struct udp_table *udptable) { struct sock *sk, *stack[256 / sizeof(struct sock *)]; - struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest)); - int dif; + struct hlist_nulls_node *node; + unsigned short hnum = ntohs(uh->dest); + struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum); + int dif = skb->dev->ifindex; unsigned int i, count = 0; spin_lock(&hslot->lock); - sk = sk_nulls_head(&hslot->head); - dif = skb->dev->ifindex; - sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); - while (sk) { - stack[count++] = sk; - sk = udp_v4_mcast_next(net, sk_nulls_next(sk), uh->dest, - daddr, uh->source, saddr, dif); - if (unlikely(count == ARRAY_SIZE(stack))) { - if (!sk) - break; - flush_stack(stack, count, skb, ~0); - count = 0; + sk_nulls_for_each(sk, node, &hslot->head) { + if (__udp_is_mcast_sock(net, sk, + uh->dest, daddr, + uh->source, saddr, + dif, hnum)) { + if (unlikely(count == ARRAY_SIZE(stack))) { + flush_stack(stack, count, skb, ~0); + count = 0; + } + stack[count++] = sk; } } /* diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c2bd28f..6bcfbb8 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -698,43 +698,26 @@ drop: return -1; } -static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, - __be16 loc_port, const struct in6_addr *loc_addr, - __be16 rmt_port, const struct in6_addr *rmt_addr, - int dif) +static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk, + __be16 loc_port, const struct in6_addr *loc_addr, + __be16 rmt_port, const struct in6_addr *rmt_addr, + int dif, unsigned short hnum) { - struct hlist_nulls_node *node; - unsigned short num = ntohs(loc_port); - - sk_nulls_for_each_from(sk, node) { - struct inet_sock *inet = inet_sk(sk); - - if (!net_eq(sock_net(sk), net)) - continue; - - if (udp_sk(sk)->udp_port_hash == num && - sk->sk_family == PF_INET6) { - if (inet->inet_dport) { - if (inet->inet_dport != rmt_port) - continue; - } - if (!ipv6_addr_any(&sk->sk_v6_daddr) && - !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) - continue; - - if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) - continue; + struct inet_sock *inet = inet_sk(sk); - if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { - if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)) - continue; - } - if (!inet6_mc_check(sk, loc_addr, rmt_addr)) - continue; - return sk; - } - } - return NULL; + if (!net_eq(sock_net(sk), net)) + return false; + + if (udp_sk(sk)->udp_port_hash != hnum || + sk->sk_family != PF_INET6 || + (inet->inet_dport && inet->inet_dport != rmt_port) || + (!ipv6_addr_any(&sk->sk_v6_daddr) && + !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) || + (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) + return false; + if (!inet6_mc_check(sk, loc_addr, rmt_addr)) + return false; + return true; } static void flush_stack(struct sock **stack, unsigned int count, @@ -783,28 +766,27 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, { struct sock *sk, *stack[256 / sizeof(struct sock *)]; const struct udphdr *uh = udp_hdr(skb); - struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest)); - int dif; + struct hlist_nulls_node *node; + unsigned short hnum = ntohs(uh->dest); + struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum); + int dif = inet6_iif(skb); unsigned int i, count = 0; spin_lock(&hslot->lock); - sk = sk_nulls_head(&hslot->head); - dif = inet6_iif(skb); - sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); - while (sk) { - /* If zero checksum and no_check is not on for - * the socket then skip it. - */ - if (uh->check || udp_sk(sk)->no_check6_rx) + sk_nulls_for_each(sk, node, &hslot->head) { + if (__udp_v6_is_mcast_sock(net, sk, + uh->dest, daddr, + uh->source, saddr, + dif, hnum) && + /* If zero checksum and no_check is not on for + * the socket then skip it. + */ + (uh->check || udp_sk(sk)->no_check6_rx)) { + if (unlikely(count == ARRAY_SIZE(stack))) { + flush_stack(stack, count, skb, ~0); + count = 0; + } stack[count++] = sk; - - sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr, - uh->source, saddr, dif); - if (unlikely(count == ARRAY_SIZE(stack))) { - if (!sk) - break; - flush_stack(stack, count, skb, ~0); - count = 0; } } /*