bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] Extending bpf_setsockopt with SO_BINDTODEVICE sockopt
@ 2020-05-21 12:52 Ferenc Fejes
  2020-05-21 19:09 ` Andrii Nakryiko
  2020-05-21 21:14 ` sdf
  0 siblings, 2 replies; 4+ messages in thread
From: Ferenc Fejes @ 2020-05-21 12:52 UTC (permalink / raw)
  To: netdev
  Cc: bpf, linux-kernel, Martin KaFai Lau, Lawrence Brakmo,
	David S . Miller, Ferenc Fejes

This option makes possible to programatically bind sockets to netdevices.
With the help of this option sockets of VRF unaware applications
could be distributed between multiple VRFs with eBPF sock_ops program.
This let the applications benefit from the multiple possible routes.

Signed-off-by: Ferenc Fejes <fejes@inf.elte.hu>
---
 net/core/filter.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index 822d662f97ef..25dac75bfc5d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4248,6 +4248,9 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = {
 static int _bpf_setsockopt(struct sock *sk, int level, int optname,
 			   char *optval, int optlen, u32 flags)
 {
+	char devname[IFNAMSIZ];
+	struct net *net;
+	int ifindex;
 	int ret = 0;
 	int val;
 
@@ -4257,7 +4260,7 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
 	sock_owned_by_me(sk);
 
 	if (level == SOL_SOCKET) {
-		if (optlen != sizeof(int))
+		if (optlen != sizeof(int) && optname != SO_BINDTODEVICE)
 			return -EINVAL;
 		val = *((int *)optval);
 
@@ -4298,6 +4301,40 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
 				sk_dst_reset(sk);
 			}
 			break;
+		case SO_BINDTODEVICE:
+			ret = -ENOPROTOOPT;
+#ifdef CONFIG_NETDEVICES
+			net = sock_net(sk);
+			strncpy(devname, optval,
+				min_t(long, optlen, IFNAMSIZ-1));
+			devname[IFNAMSIZ-1] = 0;
+			ifindex = 0;
+			if (devname[0] != '\0') {
+				struct net_device *dev;
+
+				rcu_read_lock();
+				dev = dev_get_by_name_rcu(net, devname);
+				if (dev)
+					ifindex = dev->ifindex;
+				rcu_read_unlock();
+				ret = -ENODEV;
+				if (!dev)
+					break;
+			}
+			ret = -EPERM;
+			if (sk->sk_bound_dev_if &&
+				!ns_capable(net->user_ns, CAP_NET_RAW))
+				break;
+			ret = -EINVAL;
+			if (ifindex < 0)
+				break;
+			sk->sk_bound_dev_if = ifindex;
+			if (sk->sk_prot->rehash)
+				sk->sk_prot->rehash(sk);
+			sk_dst_reset(sk);
+			ret = 0;
+#endif
+			break;
 		default:
 			ret = -EINVAL;
 		}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-21 21:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-21 12:52 [PATCH net-next] Extending bpf_setsockopt with SO_BINDTODEVICE sockopt Ferenc Fejes
2020-05-21 19:09 ` Andrii Nakryiko
2020-05-21 21:14 ` sdf
2020-05-21 21:55   ` Ferenc Fejes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).