1 #include <linux/module.h>
2 #include <linux/errno.h>
3 #include <linux/socket.h>
5 #include <linux/types.h>
6 #include <linux/kernel.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
)
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
);
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
,
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);
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
);
52 if (cfg
->family
== AF_INET
) {
53 struct sockaddr_in udp_addr
;
55 err
= sock_create_kern(AF_INET
, SOCK_DGRAM
, 0, &sock
);
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
,
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
,
80 sock
->sk
->sk_no_check_tx
= !cfg
->use_udp_checksums
;
92 kernel_sock_shutdown(sock
, SHUT_RDWR
);
93 sk_release_kernel(sock
->sk
);
98 EXPORT_SYMBOL(udp_sock_create
);
100 MODULE_LICENSE("GPL");
This page took 0.032972 seconds and 5 git commands to generate.