r8152: disable power cut for RTL8153
[linux-2.6/btrfs-unstable.git] / net / ipv4 / udp_tunnel.c
blob61ec1a65207efe07155f4e259a31659d3d183f9d
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 <net/udp.h>
8 #include <net/udp_tunnel.h>
9 #include <net/net_namespace.h>
11 int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
12 struct socket **sockp)
14 int err = -EINVAL;
15 struct socket *sock = NULL;
17 #if IS_ENABLED(CONFIG_IPV6)
18 if (cfg->family == AF_INET6) {
19 struct sockaddr_in6 udp6_addr;
21 err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
22 if (err < 0)
23 goto error;
25 sk_change_net(sock->sk, net);
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;
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);
45 if (err < 0)
46 goto error;
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;
55 err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
56 if (err < 0)
57 goto error;
59 sk_change_net(sock->sk, net);
61 udp_addr.sin_family = AF_INET;
62 udp_addr.sin_addr = cfg->local_ip;
63 udp_addr.sin_port = cfg->local_udp_port;
64 err = kernel_bind(sock, (struct sockaddr *)&udp_addr,
65 sizeof(udp_addr));
66 if (err < 0)
67 goto error;
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;
80 sock->sk->sk_no_check_tx = !cfg->use_udp_checksums;
81 } else {
82 return -EPFNOSUPPORT;
86 *sockp = sock;
88 return 0;
90 error:
91 if (sock) {
92 kernel_sock_shutdown(sock, SHUT_RDWR);
93 sk_release_kernel(sock->sk);
95 *sockp = NULL;
96 return err;
98 EXPORT_SYMBOL(udp_sock_create);
100 MODULE_LICENSE("GPL");