Commit da5095d0 authored by Alexis Bauvin's avatar Alexis Bauvin Committed by David S. Miller

udp_tunnel: add config option to bind to a device

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: default avatarAlexis Bauvin <abauvin@scaleway.com>
Reviewed-by: default avatarAmine Kherbouche <akherbouche@scaleway.com>
Tested-by: default avatarAmine Kherbouche <akherbouche@scaleway.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e3dd7627
...@@ -30,6 +30,7 @@ struct udp_port_cfg { ...@@ -30,6 +30,7 @@ struct udp_port_cfg {
__be16 local_udp_port; __be16 local_udp_port;
__be16 peer_udp_port; __be16 peer_udp_port;
int bind_ifindex;
unsigned int use_udp_checksums:1, unsigned int use_udp_checksums:1,
use_udp6_tx_checksums:1, use_udp6_tx_checksums:1,
use_udp6_rx_checksums:1, use_udp6_rx_checksums:1,
......
...@@ -20,6 +20,23 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, ...@@ -20,6 +20,23 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
if (err < 0) if (err < 0)
goto error; goto error;
if (cfg->bind_ifindex) {
struct net_device *dev;
dev = dev_get_by_index(net, cfg->bind_ifindex);
if (!dev) {
err = -ENODEV;
goto error;
}
err = kernel_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
dev->name, strlen(dev->name) + 1);
dev_put(dev);
if (err < 0)
goto error;
}
udp_addr.sin_family = AF_INET; udp_addr.sin_family = AF_INET;
udp_addr.sin_addr = cfg->local_ip; udp_addr.sin_addr = cfg->local_ip;
udp_addr.sin_port = cfg->local_udp_port; udp_addr.sin_port = cfg->local_udp_port;
......
...@@ -31,6 +31,22 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, ...@@ -31,6 +31,22 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
if (err < 0) if (err < 0)
goto error; goto error;
} }
if (cfg->bind_ifindex) {
struct net_device *dev;
dev = dev_get_by_index(net, cfg->bind_ifindex);
if (!dev) {
err = -ENODEV;
goto error;
}
err = kernel_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
dev->name, strlen(dev->name) + 1);
dev_put(dev);
if (err < 0)
goto error;
}
udp6_addr.sin6_family = AF_INET6; udp6_addr.sin6_family = AF_INET6;
memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment