From patchwork Tue Oct 23 14:21:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Emelyanov X-Patchwork-Id: 193499 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 73B4D2C0109 for ; Wed, 24 Oct 2012 01:22:36 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755090Ab2JWOWb (ORCPT ); Tue, 23 Oct 2012 10:22:31 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:23029 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754525Ab2JWOWa (ORCPT ); Tue, 23 Oct 2012 10:22:30 -0400 Received: from [10.24.20.146] ([10.24.20.146]) (authenticated bits=0) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id q9NELn56011580 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 23 Oct 2012 18:21:50 +0400 (MSK) Message-ID: <5086A7FD.3020503@parallels.com> Date: Tue, 23 Oct 2012 18:21:49 +0400 From: Pavel Emelyanov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120605 Thunderbird/13.0 MIME-Version: 1.0 To: Brian Haley , Ben Hutchings , Eric Dumazet , Linux Netdev List Subject: [PATCH net-next] sockopt: Introduce the SO_BINDTOIFINDEX Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Gentlemen, here's how the symmetrical sk_bound_dev set/get would look like. If it's OK for you, I would ask David for inclusion. It was noted that it was not good to have the non-symmetrical SO_BINDTODEVICE sockoption (set works with name, get reports index) and we'd rather implement another option to set and get socket bound device that work on ifindex. The SO_BINDTONETDEV get-er is removed, as getting a device name is tricky and having one doesn't worth that pain. Signed-off-by: Pavel Emelyanov --- include/uapi/asm-generic/socket.h | 2 + net/core/sock.c | 41 ++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index b1bea03..c99c843 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -72,4 +72,6 @@ /* Instruct lower device to use last 4-bytes of skb data as FCS */ #define SO_NOFCS 43 +#define SO_BINDTOIFINDEX 44 + #endif /* __ASM_GENERIC_SOCKET_H */ diff --git a/net/core/sock.c b/net/core/sock.c index c49412c..c4f56e9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -505,6 +505,39 @@ struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie) } EXPORT_SYMBOL(sk_dst_check); +static void sock_set_bound_dev(struct sock *sk, int idx) +{ + sk->sk_bound_dev_if = idx; + sk_dst_reset(sk); +} + +static int sock_bindtoindex(struct sock *sk, int idx) +{ + int ret = -ENOPROTOOPT; +#ifdef CONFIG_NETDEVICES + struct net *net = sock_net(sk); + + if (!capable(CAP_NET_RAW)) + return -EPERM; + + if (idx != 0) { + struct net_device *dev; + + rcu_read_lock(); + dev = dev_get_by_index_rcu(net, idx); + rcu_read_unlock(); + ret = -ENODEV; + if (!dev) + goto out; + } + + sock_set_bound_dev(sk, idx); + ret = 0; +out: +#endif + return ret; +} + static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) { int ret = -ENOPROTOOPT; @@ -550,8 +583,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) } lock_sock(sk); - sk->sk_bound_dev_if = index; - sk_dst_reset(sk); + sock_set_bound_dev(sk, index); release_sock(sk); ret = 0; @@ -839,6 +871,9 @@ set_rcvbuf: case SO_NOFCS: sock_valbool_flag(sk, SOCK_NOFCS, valbool); break; + case SO_BINDTOIFINDEX: + ret = sock_bindtoindex(sk, val); + break; default: ret = -ENOPROTOOPT; @@ -1074,7 +1109,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, case SO_NOFCS: v.val = sock_flag(sk, SOCK_NOFCS); break; - case SO_BINDTODEVICE: + case SO_BINDTOIFINDEX: v.val = sk->sk_bound_dev_if; break; default: