From patchwork Sun Aug 23 22:06:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Ricard X-Patchwork-Id: 509879 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 BD1E9140271 for ; Mon, 24 Aug 2015 08:06:46 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=Df8wFelF; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753463AbbHWWGb (ORCPT ); Sun, 23 Aug 2015 18:06:31 -0400 Received: from mail-wi0-f181.google.com ([209.85.212.181]:37875 "EHLO mail-wi0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753219AbbHWWGY (ORCPT ); Sun, 23 Aug 2015 18:06:24 -0400 Received: by widdq5 with SMTP id dq5so56467401wid.0 for ; Sun, 23 Aug 2015 15:06:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Icd+l0o8N/2DMlzoQigM5xLG0nqP4/SfTQKzhRCKib4=; b=Df8wFelFfv6wvBrlxVRPjT41NLJpN0y3AH9t9uXYHjhbv2DDgZwnM+X/bN60z9H8gK Bn7dsnc8Fewl9pLasfgOU5TwSwuE3zkqsg0+xzUHP09QvOwM/EJl7udAbR6xdb1G8RcY hNwbOSEfYkPwi2nc5hIT2rWSLIl7cw07avf3jC9Oi4OjUJTvZduq0l999nDKhLo+l9tm ic/B+xQNIJkDffyYfZeuGDZ6EKtE0XVkqtjFmsH+apSjFm7nv5UZ6rvZhuIOSqeTaf4C svji4FA0rw+AinxAyY6LtvRyI3cqnR4tAkepthV17SyhVfrIkQF/YPIbND7Lt5cVbgvY qhjQ== X-Received: by 10.195.11.202 with SMTP id ek10mr35112670wjd.12.1440367583436; Sun, 23 Aug 2015 15:06:23 -0700 (PDT) Received: from localhost.localdomain (ax113-6-78-236-204-66.fbx.proxad.net. [78.236.204.66]) by smtp.gmail.com with ESMTPSA id fq15sm20317124wjc.12.2015.08.23.15.06.22 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 23 Aug 2015 15:06:22 -0700 (PDT) From: Christophe Ricard X-Google-Original-From: Christophe Ricard To: pablo@netfilter.org, jbenc@redhat.com, sameo@linux.intel.com Cc: netdev@vger.kernel.org, davem@davemloft.net, Christophe Ricard Subject: [RFC] netlink: netlink_ack send a capped message in case of error Date: Mon, 24 Aug 2015 00:06:17 +0200 Message-Id: <1440367577-15786-2-git-send-email-christophe-h.ricard@st.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1440367577-15786-1-git-send-email-christophe-h.ricard@st.com> References: <1440367577-15786-1-git-send-email-christophe-h.ricard@st.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently, ACK in case of error contains a full copy of the originating message. This can cause lost ACKs with large netlink messages, especially after commit c05cdb1b864f ("netlink: allow large data transfers from user-space"). Send back a capped message instead. Signed-off-by: Christophe Ricard --- net/netlink/af_netlink.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 67d2104..9df862c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -85,6 +85,9 @@ struct listeners { #define NETLINK_F_RECV_NO_ENOBUFS 0x8 #define NETLINK_F_LISTEN_ALL_NSID 0x10 +/* Arbitrary value for a small message less than PAGE_SIZE */ +#define NETLINK_ERR_MESSAGE_CAP 128 + static inline int netlink_is_kernel(struct sock *sk) { return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET; @@ -2873,10 +2876,15 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) struct nlmsghdr *rep; struct nlmsgerr *errmsg; size_t payload = sizeof(*errmsg); + size_t size = 0; - /* error messages get the original request appened */ - if (err) - payload += nlmsg_len(nlh); + /* error messages get a cap request appened */ + if (err) { + payload += nlmsg_len(nlh) > NETLINK_ERR_MESSAGE_CAP ? + NETLINK_ERR_MESSAGE_CAP : nlmsg_len(nlh); + size = nlmsg_len(nlh) > NETLINK_ERR_MESSAGE_CAP ? + (NETLINK_ERR_MESSAGE_CAP + NLMSG_HDRLEN) : nlh->nlmsg_len; + } skb = netlink_alloc_skb(in_skb->sk, nlmsg_total_size(payload), NETLINK_CB(in_skb).portid, GFP_KERNEL); @@ -2898,7 +2906,8 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) NLMSG_ERROR, payload, 0); errmsg = nlmsg_data(rep); errmsg->error = err; - memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh)); + + memcpy(&errmsg->msg, nlh, err ? size : sizeof(*nlh)); netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT); } EXPORT_SYMBOL(netlink_ack);