From patchwork Thu Apr 26 17:42:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 905289 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="i/0YCXQw"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40X4D11wZ3z9ry1 for ; Fri, 27 Apr 2018 03:43:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932340AbeDZRnL (ORCPT ); Thu, 26 Apr 2018 13:43:11 -0400 Received: from mail-qk0-f195.google.com ([209.85.220.195]:39833 "EHLO mail-qk0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932177AbeDZRmd (ORCPT ); Thu, 26 Apr 2018 13:42:33 -0400 Received: by mail-qk0-f195.google.com with SMTP id z75so15255881qkb.6 for ; Thu, 26 Apr 2018 10:42:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ln7Av1ay+NAN76hv1AeROwM6UjJ1Nvmnrt7yu6GUSZc=; b=i/0YCXQw/mLTzHzerIS4tZry8/Bpo/eXnz+TM3FAOwD9DJK7gcVdulD9pLjDbwBJ+Z vtDsC6jtFBFGgoE2OOQigXznEcSh1vIoQQU08jdihJKkb0Ld6oCwh4O/1XonLiPnG+fY qYHyt8iU3uNjdUMEANzVN/wPFYfHgvI09Fm+2MZLZ2SZD0fa8uZkxL6z9GhHtmRFxASh j6XGWl3YsNPzBg8KCfpGZQCP2tera+sdv3lsXKvYuppzfaflJW2mrvWlgrzoNjkSRNhf 8lxe0A1uQqbg6BkhQvKGiw5m8KJ0zddlsOpGaAYih5Hn3v3paNovBY7ZDSvZIDDw5EWy yikA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ln7Av1ay+NAN76hv1AeROwM6UjJ1Nvmnrt7yu6GUSZc=; b=tl4WnbYI2tZuuJcTujKAvFV0Z+eJNlKnbDChRglOtF7w+UM7resHfnQ1cEANNGO46p pfL6IQuhTPfPNZwKG0nZGN8i9AvWdpi0c+/kTZEL0aW2kh64PvgkOsBDciiO/4g88mLy C0NiFs711YyV0I+JmbEYH0Q5HWFIsAdL2LfLg1czmMEgMTx28UOJ0+XAMYdZPgrIIo2f t0j64wgeto8ybCq6iGGbYT0D9tI+9G0WZYuXr6BqaPWYmLvEgnv/UahgryDchEBBwk37 In/X/KR2PRfQ3TPgG8BdAgyx5qA2Jvp/69x1D10Cq37XKkFS4bzNG1VC/QOzeaBWg/0t Ig7w== X-Gm-Message-State: ALQs6tAHN8HL9AdB+AfOVxHM+yI54KWzcCvU5K0zwAOAJiz1HnbNS2qK UwhlBWSvFUInevwhIY7sv9cas1xc X-Google-Smtp-Source: AB8JxZobpOsIA3wjugiZOqWQHsxfcaq6Mi5gpx+3JGCuJ0e3/uBPERgEQWnHKi9forJ/QWg7TRe1wA== X-Received: by 10.55.153.133 with SMTP id b127mr30223377qke.43.1524764551965; Thu, 26 Apr 2018 10:42:31 -0700 (PDT) Received: from willemb1.nyc.corp.google.com ([2620:0:1003:315:3fa1:a34c:1128:1d39]) by smtp.gmail.com with ESMTPSA id o14-v6sm12927515qta.23.2018.04.26.10.42.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Apr 2018 10:42:31 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, alexander.duyck@gmail.com, Willem de Bruijn Subject: [PATCH net-next v2 06/11] udp: add gso segment cmsg Date: Thu, 26 Apr 2018 13:42:20 -0400 Message-Id: <20180426174225.246388-7-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.17.0.484.g0c8726318c-goog In-Reply-To: <20180426174225.246388-1-willemdebruijn.kernel@gmail.com> References: <20180426174225.246388-1-willemdebruijn.kernel@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn Allow specifying segment size in the send call. The new control message performs the same function as socket option UDP_SEGMENT while avoiding the extra system call. Signed-off-by: Willem de Bruijn --- include/net/udp.h | 1 + net/ipv4/udp.c | 43 +++++++++++++++++++++++++++++++++++++++++-- net/ipv6/udp.c | 5 ++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/net/udp.h b/include/net/udp.h index 741d888d0fdb..05990746810e 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -273,6 +273,7 @@ int udp_abort(struct sock *sk, int err); int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); int udp_push_pending_frames(struct sock *sk); void udp_flush_pending_frames(struct sock *sk); +int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size); void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst); int udp_rcv(struct sk_buff *skb); int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index bda022c5480b..350bdafc462b 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -853,6 +853,42 @@ int udp_push_pending_frames(struct sock *sk) } EXPORT_SYMBOL(udp_push_pending_frames); +static int __udp_cmsg_send(struct cmsghdr *cmsg, u16 *gso_size) +{ + switch (cmsg->cmsg_type) { + case UDP_SEGMENT: + if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u16))) + return -EINVAL; + *gso_size = *(__u16 *)CMSG_DATA(cmsg); + return 0; + default: + return -EINVAL; + } +} + +int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size) +{ + struct cmsghdr *cmsg; + bool need_ip = false; + int err; + + for_each_cmsghdr(cmsg, msg) { + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + + if (cmsg->cmsg_level != SOL_UDP) { + need_ip = true; + continue; + } + + err = __udp_cmsg_send(cmsg, gso_size); + if (err) + return err; + } + + return need_ip; +} + int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) { struct inet_sock *inet = inet_sk(sk); @@ -941,8 +977,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ipc.gso_size = up->gso_size; if (msg->msg_controllen) { - err = ip_cmsg_send(sk, msg, &ipc, sk->sk_family == AF_INET6); - if (unlikely(err)) { + err = udp_cmsg_send(sk, msg, &ipc.gso_size); + if (err > 0) + err = ip_cmsg_send(sk, msg, &ipc, + sk->sk_family == AF_INET6); + if (unlikely(err < 0)) { kfree(ipc.opt); return err; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 86b7dd58d4b4..6acfdd3e442b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1276,7 +1276,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) opt->tot_len = sizeof(*opt); ipc6.opt = opt; - err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); + err = udp_cmsg_send(sk, msg, &ipc6.gso_size); + if (err > 0) + err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, + &ipc6, &sockc); if (err < 0) { fl6_sock_release(flowlabel); return err;