From patchwork Fri Mar 19 00:24:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 48089 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 C0DF0B7C09 for ; Fri, 19 Mar 2010 11:24:58 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751592Ab0CSAYw (ORCPT ); Thu, 18 Mar 2010 20:24:52 -0400 Received: from mail.us.es ([193.147.175.20]:36055 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751145Ab0CSAYv (ORCPT ); Thu, 18 Mar 2010 20:24:51 -0400 Received: (qmail 30599 invoked from network); 19 Mar 2010 01:24:49 +0100 Received: from unknown (HELO us.es) (192.168.2.12) by us.es with SMTP; 19 Mar 2010 01:24:49 +0100 Received: (qmail 13164 invoked by uid 507); 19 Mar 2010 00:24:48 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on antivirus2 X-Spam-Level: * X-Spam-Status: No, score=1.6 required=6.5 tests=BAYES_50,RCVD_IN_PBL, RCVD_IN_SORBS_WEB,RDNS_NONE autolearn=disabled version=3.2.5 Received: from 127.0.0.1 by antivirus2 (envelope-from , uid 501) with qmail-scanner-2.06 (clamdscan: 0.95.3/10595. Clear:RC:1(127.0.0.1):. Processed in 0.046466 secs); 19 Mar 2010 00:24:48 -0000 Received: from unknown (HELO us.es) (127.0.0.1) by us.es with SMTP; 19 Mar 2010 00:24:48 -0000 Received: (qmail 8921 invoked from network); 19 Mar 2010 01:24:47 +0100 Received: from unknown (HELO ?77.208.129.91?) (pneira@us.es@77.208.129.91) by us.es with (DHE-RSA-AES256-SHA encrypted) SMTP; 19 Mar 2010 01:24:47 +0100 Message-ID: <4BA2C44A.1000100@netfilter.org> Date: Fri, 19 Mar 2010 01:24:42 +0100 From: Pablo Neira Ayuso User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090706) MIME-Version: 1.0 To: Patrick McHardy CC: netdev@vger.kernel.org, davem@davemloft.net Subject: Re: [PATCH 1/3] netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err() References: <20100316232247.4185.19426.stgit@decadence> <20100316232957.4185.46217.stgit@decadence> <4BA0F4C0.8050901@trash.net> <4BA10095.2030905@netfilter.org> <4BA22463.6050601@trash.net> <4BA25612.3080804@netfilter.org> <4BA258F6.1050909@trash.net> <4BA25C82.7000301@netfilter.org> <4BA26138.6070709@trash.net> In-Reply-To: <4BA26138.6070709@trash.net> X-Enigmail-Version: 0.95.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Patrick McHardy wrote: > Generally the logic seems inverted, you should return an error > to conntrack if userspace wasn't notified of the error. Indeed, thanks. Are you OK with this patch instead? netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err() Currently, ENOBUFS errors are reported to the socket via netlink_set_err() even if NETLINK_RECV_NO_ENOBUFS is set. However, that should not happen. This fixes this problem and it changes the prototype of netlink_set_err() to return the number of sockets that have set the NETLINK_RECV_NO_ENOBUFS socket option. This return value is used in the next patch in these bugfix series. Signed-off-by: Pablo Neira Ayuso --- include/linux/netlink.h | 2 +- net/netlink/af_netlink.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fde27c0..6eaca5e 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct sock *sk, unsigned int group); extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, __u32 group, gfp_t allocation); -extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); +extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); extern int netlink_register_notifier(struct notifier_block *nb); extern int netlink_unregister_notifier(struct notifier_block *nb); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 4c5972b..0052d3c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) { struct netlink_sock *nlk = nlk_sk(sk); + int ret = 0; if (sk == p->exclude_sk) goto out; @@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct sock *sk, !test_bit(p->group - 1, nlk->groups)) goto out; + if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) { + ret = 1; + goto out; + } + sk->sk_err = p->code; sk->sk_error_report(sk); out: - return 0; + return ret; } /** @@ -1116,12 +1122,16 @@ out: * @pid: the PID of a process that we want to skip (if any) * @groups: the broadcast group that will notice the error * @code: error code, must be negative (as usual in kernelspace) + * + * This function returns the number of broadcast listeners that have set the + * NETLINK_RECV_NO_ENOBUFS socket option. */ -void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) +int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) { struct netlink_set_err_data info; struct hlist_node *node; struct sock *sk; + int ret = 0; info.exclude_sk = ssk; info.pid = pid; @@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) read_lock(&nl_table_lock); sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) - do_one_set_err(sk, &info); + ret += do_one_set_err(sk, &info); read_unlock(&nl_table_lock); + return ret; } EXPORT_SYMBOL(netlink_set_err);