Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc7 100 lines 2.3 kB view raw
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> 10 11int udp_sock_create(struct net *net, struct udp_port_cfg *cfg, 12 struct socket **sockp) 13{ 14 int err = -EINVAL; 15 struct socket *sock = NULL; 16 17#if IS_ENABLED(CONFIG_IPV6) 18 if (cfg->family == AF_INET6) { 19 struct sockaddr_in6 udp6_addr; 20 21 err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock); 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 59 sk_change_net(sock->sk, net); 60 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; 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 } 84 85 86 *sockp = sock; 87 88 return 0; 89 90error: 91 if (sock) { 92 kernel_sock_shutdown(sock, SHUT_RDWR); 93 sk_release_kernel(sock->sk); 94 } 95 *sockp = NULL; 96 return err; 97} 98EXPORT_SYMBOL(udp_sock_create); 99 100MODULE_LICENSE("GPL");