From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexis Bauvin Subject: [PATCH v5 1/6] udp_tunnel: add config option to bind to a device Date: Tue, 27 Nov 2018 02:03:52 +0100 Message-ID: <20181127010357.59070-2-abauvin@scaleway.com> References: <20181127010357.59070-1-abauvin@scaleway.com> Cc: netdev@vger.kernel.org, abauvin@scaleway.com, akherbouche@scaleway.com To: dsa@cumulusnetworks.com, roopa@cumulusnetworks.com, stephen@networkplumber.org Return-path: Received: from mail.online.net ([62.210.16.11]:49382 "EHLO mail.online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727689AbeK0MAW (ORCPT ); Tue, 27 Nov 2018 07:00:22 -0500 In-Reply-To: <20181127010357.59070-1-abauvin@scaleway.com> Sender: netdev-owner@vger.kernel.org List-ID: UDP tunnel sockets are always opened unbound to a specific device. This patch allow the socket to be bound on a custom device, which incidentally makes UDP tunnels VRF-aware if binding to an l3mdev. Signed-off-by: Alexis Bauvin Reviewed-by: Amine Kherbouche Reviewed-by: David Ahern Tested-by: Amine Kherbouche --- include/net/udp_tunnel.h | 1 + net/ipv4/udp_tunnel.c | 10 ++++++++++ net/ipv6/ip6_udp_tunnel.c | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h index fe680ab6b15a..9f7970d010f9 100644 --- a/include/net/udp_tunnel.h +++ b/include/net/udp_tunnel.h @@ -30,6 +30,7 @@ struct udp_port_cfg { __be16 local_udp_port; __be16 peer_udp_port; + int bind_ifindex; unsigned int use_udp_checksums:1, use_udp6_tx_checksums:1, use_udp6_rx_checksums:1, diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c index 6539ff15e9a3..dc68e15a4f72 100644 --- a/net/ipv4/udp_tunnel.c +++ b/net/ipv4/udp_tunnel.c @@ -20,6 +20,16 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, if (err < 0) goto error; + if (cfg->bind_ifindex) { + struct net_device *dev; + + dev = __dev_get_by_index(net, cfg->bind_ifindex); + err = kernel_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, + dev->name, strlen(dev->name) + 1); + if (err < 0) + goto error; + } + udp_addr.sin_family = AF_INET; udp_addr.sin_addr = cfg->local_ip; udp_addr.sin_port = cfg->local_udp_port; diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c index b283f293ee4a..fc3811ef8787 100644 --- a/net/ipv6/ip6_udp_tunnel.c +++ b/net/ipv6/ip6_udp_tunnel.c @@ -31,6 +31,15 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, if (err < 0) goto error; } + if (cfg->bind_ifindex) { + struct net_device *dev; + + dev = __dev_get_by_index(net, cfg->bind_ifindex); + err = kernel_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, + dev->name, strlen(dev->name) + 1); + if (err < 0) + goto error; + } udp6_addr.sin6_family = AF_INET6; memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, --