From patchwork Wed Feb 18 11:40:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 23338 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.176.167]) by ozlabs.org (Postfix) with ESMTP id 28718DDE11 for ; Wed, 18 Feb 2009 22:41:05 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751574AbZBRLkx (ORCPT ); Wed, 18 Feb 2009 06:40:53 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751494AbZBRLkx (ORCPT ); Wed, 18 Feb 2009 06:40:53 -0500 Received: from mail.us.es ([193.147.175.20]:59716 "EHLO us.es" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751453AbZBRLkw (ORCPT ); Wed, 18 Feb 2009 06:40:52 -0500 Received: (qmail 2910 invoked from network); 18 Feb 2009 12:40:48 +0100 Received: from unknown (HELO us.es) (192.168.2.15) by us.es with SMTP; 18 Feb 2009 12:40:48 +0100 Received: (qmail 29452 invoked by uid 507); 18 Feb 2009 11:40:49 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on antivirus4 X-Spam-Level: X-Spam-Status: No, score=0.1 required=6.5 tests=BAYES_50,RDNS_NONE autolearn=disabled version=3.2.5 Received: from 127.0.0.1 by antivirus4 (envelope-from , uid 501) with qmail-scanner-2.04 (clamdscan: 0.94.2/9001. Clear:RC:1(127.0.0.1):. Processed in 0.011638 secs); 18 Feb 2009 11:40:49 -0000 Received: from unknown (HELO us.es) (127.0.0.1) by us.es with SMTP; 18 Feb 2009 11:40:49 -0000 Received: (qmail 25416 invoked from network); 18 Feb 2009 12:40:45 +0100 Received: from unknown (HELO ?127.0.1.1?) (pneira@us.es@89.130.131.28) by us.es with (DHE-RSA-AES256-SHA encrypted) SMTP; 18 Feb 2009 12:40:45 +0100 From: Pablo Neira Ayuso Subject: [PATCH] netlink: add NETLINK_BROADCAST_ERROR socket option To: netdev@vger.kernel.org Cc: kaber@trash.net, davem@davemloft.net Date: Wed, 18 Feb 2009 12:40:43 +0100 Message-ID: <20090218114042.7060.54127.stgit@Decadence> User-Agent: StGIT/0.14.2 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds NETLINK_BROADCAST_ERROR which is a netlink socket option that the listener can set to make netlink_broadcast() return errors in the delivery to the caller. This option is useful if the caller of netlink_broadcast() do something with the result of the message delivery, like in ctnetlink where it drops a network packet if the event delivery failed, this is used to enable reliable logging and state-synchronization. If this socket option is not set, netlink_broadcast() only reports ESRCH errors and silently ignore ENOBUFS errors, which is what most netlink_broadcast() callers should do. This socket option is based on a suggestion from Patrick McHardy. Patrick McHardy can exchange this patch for a beer from me ;). Signed-off-by: Pablo Neira Ayuso Acked-by: Patrick McHardy --- include/linux/netlink.h | 1 + net/netlink/af_netlink.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 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/include/linux/netlink.h b/include/linux/netlink.h index 51b09a1..1e6bf99 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -103,6 +103,7 @@ struct nlmsgerr #define NETLINK_ADD_MEMBERSHIP 1 #define NETLINK_DROP_MEMBERSHIP 2 #define NETLINK_PKTINFO 3 +#define NETLINK_BROADCAST_ERROR 4 struct nl_pktinfo { diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 6ee69c2..ed587be 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -85,6 +85,7 @@ struct netlink_sock { #define NETLINK_KERNEL_SOCKET 0x1 #define NETLINK_RECV_PKTINFO 0x2 +#define NETLINK_BROADCAST_SEND_ERROR 0x4 static inline struct netlink_sock *nlk_sk(struct sock *sk) { @@ -995,12 +996,15 @@ static inline int do_one_broadcast(struct sock *sk, netlink_overrun(sk); /* Clone failed. Notify ALL listeners. */ p->failure = 1; + if (nlk->flags & NETLINK_BROADCAST_SEND_ERROR) + p->delivery_failure = 1; } else if (sk_filter(sk, p->skb2)) { kfree_skb(p->skb2); p->skb2 = NULL; } else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) { netlink_overrun(sk); - p->delivery_failure = 1; + if (nlk->flags & NETLINK_BROADCAST_SEND_ERROR) + p->delivery_failure = 1; } else { p->congested |= val; p->delivered = 1; @@ -1048,7 +1052,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, if (info.skb2) kfree_skb(info.skb2); - if (info.delivery_failure || info.failure) + if (info.delivery_failure) return -ENOBUFS; if (info.delivered) { @@ -1163,6 +1167,13 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, err = 0; break; } + case NETLINK_BROADCAST_ERROR: + if (val) + nlk->flags |= NETLINK_BROADCAST_SEND_ERROR; + else + nlk->flags &= ~NETLINK_BROADCAST_SEND_ERROR; + err = 0; + break; default: err = -ENOPROTOOPT; } @@ -1195,6 +1206,16 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, return -EFAULT; err = 0; break; + case NETLINK_BROADCAST_ERROR: + if (len < sizeof(int)) + return -EINVAL; + len = sizeof(int); + val = nlk->flags & NETLINK_BROADCAST_SEND_ERROR ? 1 : 0; + if (put_user(len, optlen) || + put_user(val, optval)) + return -EFAULT; + err = 0; + break; default: err = -ENOPROTOOPT; }