aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2014-09-16 20:31:16 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-19 15:57:15 -0400
commitfd384412e199b62c3ddaabd18dce86d0e164c5b9 (patch)
tree88c3a930da306688b23767a2be6ac2826e5826b5
parent79ba2b4c5d3779d68b4cd3a569d483f1778f2b5a (diff)
udp_tunnel: Seperate ipv6 functions into its own file.
Add ip6_udp_tunnel.c for ipv6 UDP tunnel functions to avoid ifdefs in udp_tunnel.c Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/udp_tunnel.h28
-rw-r--r--net/ipv4/udp_tunnel.c85
-rw-r--r--net/ipv6/Makefile1
-rw-r--r--net/ipv6/ip6_udp_tunnel.c63
4 files changed, 111 insertions, 66 deletions
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index ffd69cbded35..0b9e017c9038 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -26,7 +26,31 @@ struct udp_port_cfg {
26 use_udp6_rx_checksums:1; 26 use_udp6_rx_checksums:1;
27}; 27};
28 28
29int udp_sock_create(struct net *net, struct udp_port_cfg *cfg, 29int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
30 struct socket **sockp); 30 struct socket **sockp);
31
32#if IS_ENABLED(CONFIG_IPV6)
33int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
34 struct socket **sockp);
35#else
36static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
37 struct socket **sockp)
38{
39 return 0;
40}
41#endif
42
43static inline int udp_sock_create(struct net *net,
44 struct udp_port_cfg *cfg,
45 struct socket **sockp)
46{
47 if (cfg->family == AF_INET)
48 return udp_sock_create4(net, cfg, sockp);
49
50 if (cfg->family == AF_INET6)
51 return udp_sock_create6(net, cfg, sockp);
52
53 return -EPFNOSUPPORT;
54}
31 55
32#endif 56#endif
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
index 61ec1a65207e..7fccf6c3417a 100644
--- a/net/ipv4/udp_tunnel.c
+++ b/net/ipv4/udp_tunnel.c
@@ -8,83 +8,40 @@
8#include <net/udp_tunnel.h> 8#include <net/udp_tunnel.h>
9#include <net/net_namespace.h> 9#include <net/net_namespace.h>
10 10
11int udp_sock_create(struct net *net, struct udp_port_cfg *cfg, 11int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
12 struct socket **sockp) 12 struct socket **sockp)
13{ 13{
14 int err = -EINVAL; 14 int err = -EINVAL;
15 struct socket *sock = NULL; 15 struct socket *sock = NULL;
16 struct sockaddr_in udp_addr;
16 17
17#if IS_ENABLED(CONFIG_IPV6) 18 err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
18 if (cfg->family == AF_INET6) { 19 if (err < 0)
19 struct sockaddr_in6 udp6_addr; 20 goto error;
20 21
21 err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock); 22 sk_change_net(sock->sk, net);
22 if (err < 0)
23 goto error;
24
25 sk_change_net(sock->sk, net);
26
27 udp6_addr.sin6_family = AF_INET6;
28 memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
29 sizeof(udp6_addr.sin6_addr));
30 udp6_addr.sin6_port = cfg->local_udp_port;
31 err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
32 sizeof(udp6_addr));
33 if (err < 0)
34 goto error;
35
36 if (cfg->peer_udp_port) {
37 udp6_addr.sin6_family = AF_INET6;
38 memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
39 sizeof(udp6_addr.sin6_addr));
40 udp6_addr.sin6_port = cfg->peer_udp_port;
41 err = kernel_connect(sock,
42 (struct sockaddr *)&udp6_addr,
43 sizeof(udp6_addr), 0);
44 }
45 if (err < 0)
46 goto error;
47
48 udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
49 udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
50 } else
51#endif
52 if (cfg->family == AF_INET) {
53 struct sockaddr_in udp_addr;
54
55 err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
56 if (err < 0)
57 goto error;
58 23
59 sk_change_net(sock->sk, net); 24 udp_addr.sin_family = AF_INET;
25 udp_addr.sin_addr = cfg->local_ip;
26 udp_addr.sin_port = cfg->local_udp_port;
27 err = kernel_bind(sock, (struct sockaddr *)&udp_addr,
28 sizeof(udp_addr));
29 if (err < 0)
30 goto error;
60 31
32 if (cfg->peer_udp_port) {
61 udp_addr.sin_family = AF_INET; 33 udp_addr.sin_family = AF_INET;
62 udp_addr.sin_addr = cfg->local_ip; 34 udp_addr.sin_addr = cfg->peer_ip;
63 udp_addr.sin_port = cfg->local_udp_port; 35 udp_addr.sin_port = cfg->peer_udp_port;
64 err = kernel_bind(sock, (struct sockaddr *)&udp_addr, 36 err = kernel_connect(sock, (struct sockaddr *)&udp_addr,
65 sizeof(udp_addr)); 37 sizeof(udp_addr), 0);
66 if (err < 0) 38 if (err < 0)
67 goto error; 39 goto error;
68
69 if (cfg->peer_udp_port) {
70 udp_addr.sin_family = AF_INET;
71 udp_addr.sin_addr = cfg->peer_ip;
72 udp_addr.sin_port = cfg->peer_udp_port;
73 err = kernel_connect(sock,
74 (struct sockaddr *)&udp_addr,
75 sizeof(udp_addr), 0);
76 if (err < 0)
77 goto error;
78 }
79
80 sock->sk->sk_no_check_tx = !cfg->use_udp_checksums;
81 } else {
82 return -EPFNOSUPPORT;
83 } 40 }
84 41
42 sock->sk->sk_no_check_tx = !cfg->use_udp_checksums;
85 43
86 *sockp = sock; 44 *sockp = sock;
87
88 return 0; 45 return 0;
89 46
90error: 47error:
@@ -95,6 +52,6 @@ error:
95 *sockp = NULL; 52 *sockp = NULL;
96 return err; 53 return err;
97} 54}
98EXPORT_SYMBOL(udp_sock_create); 55EXPORT_SYMBOL(udp_sock_create4);
99 56
100MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 2fe68364bb20..45f830e5f820 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
35obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o 35obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
36obj-$(CONFIG_IPV6_MIP6) += mip6.o 36obj-$(CONFIG_IPV6_MIP6) += mip6.o
37obj-$(CONFIG_NETFILTER) += netfilter/ 37obj-$(CONFIG_NETFILTER) += netfilter/
38obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
38 39
39obj-$(CONFIG_IPV6_VTI) += ip6_vti.o 40obj-$(CONFIG_IPV6_VTI) += ip6_vti.o
40obj-$(CONFIG_IPV6_SIT) += sit.o 41obj-$(CONFIG_IPV6_SIT) += sit.o
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
new file mode 100644
index 000000000000..bcfbb4b496fc
--- /dev/null
+++ b/net/ipv6/ip6_udp_tunnel.c
@@ -0,0 +1,63 @@
1#include <linux/module.h>
2#include <linux/errno.h>
3#include <linux/socket.h>
4#include <linux/udp.h>
5#include <linux/types.h>
6#include <linux/kernel.h>
7#include <linux/in6.h>
8#include <net/udp.h>
9#include <net/udp_tunnel.h>
10#include <net/net_namespace.h>
11#include <net/netns/generic.h>
12#include <net/ip6_tunnel.h>
13#include <net/ip6_checksum.h>
14
15int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
16 struct socket **sockp)
17{
18 struct sockaddr_in6 udp6_addr;
19 int err;
20 struct socket *sock = NULL;
21
22 err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
23 if (err < 0)
24 goto error;
25
26 sk_change_net(sock->sk, net);
27
28 udp6_addr.sin6_family = AF_INET6;
29 memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
30 sizeof(udp6_addr.sin6_addr));
31 udp6_addr.sin6_port = cfg->local_udp_port;
32 err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
33 sizeof(udp6_addr));
34 if (err < 0)
35 goto error;
36
37 if (cfg->peer_udp_port) {
38 udp6_addr.sin6_family = AF_INET6;
39 memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
40 sizeof(udp6_addr.sin6_addr));
41 udp6_addr.sin6_port = cfg->peer_udp_port;
42 err = kernel_connect(sock,
43 (struct sockaddr *)&udp6_addr,
44 sizeof(udp6_addr), 0);
45 }
46 if (err < 0)
47 goto error;
48
49 udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
50 udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
51
52 *sockp = sock;
53 return 0;
54
55error:
56 if (sock) {
57 kernel_sock_shutdown(sock, SHUT_RDWR);
58 sk_release_kernel(sock->sk);
59 }
60 *sockp = NULL;
61 return err;
62}
63EXPORT_SYMBOL_GPL(udp_sock_create6);