forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
datapath: Account for "udp: Add udp_sock_create for UDP tunnels to op…
…en listener socket" Upstream commit: udp: Add udp_sock_create for UDP tunnels to open listener socket Added udp_tunnel.c which can contain some common functions for UDP tunnels. The first function in this is udp_sock_create which is used to open the listener port for a UDP tunnel. Signed-off-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]> Upstream: 8024e028 ("udp: Add udp_sock_create for UDP tunnels to open listener socket") Signed-off-by: Jesse Gross <[email protected]> Acked-by: Thomas Graf <[email protected]>
- Loading branch information
1 parent
de15b10
commit eb6eebd
Showing
4 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ | |
/time.c | ||
/tmp | ||
/tunnel.c | ||
/udp_tunnel.c | ||
/utils.c | ||
/vlan.c | ||
/vport-generic.c | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#ifndef __NET_UDP_TUNNEL_WRAPPER_H | ||
#define __NET_UDP_TUNNEL_WRAPPER_H | ||
|
||
#include <linux/version.h> | ||
#include <linux/kconfig.h> | ||
|
||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) | ||
#include_next <net/udp_tunnel.h> | ||
#else | ||
|
||
struct udp_port_cfg { | ||
u8 family; | ||
|
||
/* Used only for kernel-created sockets */ | ||
union { | ||
struct in_addr local_ip; | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
struct in6_addr local_ip6; | ||
#endif | ||
}; | ||
|
||
union { | ||
struct in_addr peer_ip; | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
struct in6_addr peer_ip6; | ||
#endif | ||
}; | ||
|
||
__be16 local_udp_port; | ||
__be16 peer_udp_port; | ||
unsigned int use_udp_checksums:1, | ||
use_udp6_tx_checksums:1, | ||
use_udp6_rx_checksums:1; | ||
}; | ||
|
||
int udp_sock_create(struct net *net, struct udp_port_cfg *cfg, | ||
struct socket **sockp); | ||
|
||
#endif /* Linux version < 3.17 */ | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#include <linux/version.h> | ||
|
||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) | ||
|
||
#include <linux/module.h> | ||
#include <linux/errno.h> | ||
#include <linux/socket.h> | ||
#include <linux/udp.h> | ||
#include <linux/types.h> | ||
#include <linux/kernel.h> | ||
#include <net/udp.h> | ||
#include <net/udp_tunnel.h> | ||
#include <net/net_namespace.h> | ||
|
||
int udp_sock_create(struct net *net, struct udp_port_cfg *cfg, | ||
struct socket **sockp) | ||
{ | ||
int err = -EINVAL; | ||
struct socket *sock = NULL; | ||
|
||
#if IS_ENABLED(CONFIG_IPV6) | ||
if (cfg->family == AF_INET6) { | ||
struct sockaddr_in6 udp6_addr; | ||
|
||
err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock); | ||
if (err < 0) | ||
goto error; | ||
|
||
sk_change_net(sock->sk, net); | ||
|
||
udp6_addr.sin6_family = AF_INET6; | ||
memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, | ||
sizeof(udp6_addr.sin6_addr)); | ||
udp6_addr.sin6_port = cfg->local_udp_port; | ||
err = kernel_bind(sock, (struct sockaddr *)&udp6_addr, | ||
sizeof(udp6_addr)); | ||
if (err < 0) | ||
goto error; | ||
|
||
if (cfg->peer_udp_port) { | ||
udp6_addr.sin6_family = AF_INET6; | ||
memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6, | ||
sizeof(udp6_addr.sin6_addr)); | ||
udp6_addr.sin6_port = cfg->peer_udp_port; | ||
err = kernel_connect(sock, | ||
(struct sockaddr *)&udp6_addr, | ||
sizeof(udp6_addr), 0); | ||
} | ||
if (err < 0) | ||
goto error; | ||
} else | ||
#endif | ||
if (cfg->family == AF_INET) { | ||
struct sockaddr_in udp_addr; | ||
|
||
err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock); | ||
if (err < 0) | ||
goto error; | ||
|
||
sk_change_net(sock->sk, net); | ||
|
||
udp_addr.sin_family = AF_INET; | ||
udp_addr.sin_addr = cfg->local_ip; | ||
udp_addr.sin_port = cfg->local_udp_port; | ||
err = kernel_bind(sock, (struct sockaddr *)&udp_addr, | ||
sizeof(udp_addr)); | ||
if (err < 0) | ||
goto error; | ||
|
||
if (cfg->peer_udp_port) { | ||
udp_addr.sin_family = AF_INET; | ||
udp_addr.sin_addr = cfg->peer_ip; | ||
udp_addr.sin_port = cfg->peer_udp_port; | ||
err = kernel_connect(sock, | ||
(struct sockaddr *)&udp_addr, | ||
sizeof(udp_addr), 0); | ||
if (err < 0) | ||
goto error; | ||
} | ||
} else { | ||
return -EPFNOSUPPORT; | ||
} | ||
|
||
|
||
*sockp = sock; | ||
|
||
return 0; | ||
|
||
error: | ||
if (sock) { | ||
kernel_sock_shutdown(sock, SHUT_RDWR); | ||
sk_release_kernel(sock->sk); | ||
} | ||
*sockp = NULL; | ||
return err; | ||
} | ||
|
||
#endif /* Linux version < 3.17 */ |