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/dst_metadata.h>
8#include <net/net_namespace.h>
9#include <net/udp.h>
10#include <net/udp_tunnel.h>
11
12static void __udp_tunnel_pull_rx_port(struct net_device *dev,
13 struct udp_tunnel_info *ti);
14
15int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
16 struct socket **sockp)
17{
18 int err;
19 struct socket *sock = NULL;
20 struct sockaddr_in udp_addr;
21
22 err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
23 if (err < 0)
24 goto error;
25
26 sk_change_net(sock->sk, net);
27
28 udp_addr.sin_family = AF_INET;
29 udp_addr.sin_addr = cfg->local_ip;
30 udp_addr.sin_port = cfg->local_udp_port;
31 err = kernel_bind(sock, (struct sockaddr *)&udp_addr,
32 sizeof(udp_addr));
33 if (err < 0)
34 goto error;
35
36 if (cfg->peer_udp_port) {
37 udp_addr.sin_family = AF_INET;
38 udp_addr.sin_addr = cfg->peer_ip;
39 udp_addr.sin_port = cfg->peer_udp_port;
40 err = kernel_connect(sock, (struct sockaddr *)&udp_addr,
41 sizeof(udp_addr), 0);
42 if (err < 0)
43 goto error;
44 }
45
46 sock->sk->sk_no_check_tx = !cfg->use_udp_checksums;
47
48 *sockp = sock;
49 return 0;
50
51error:
52 if (sock) {
53 kernel_sock_shutdown(sock, SHUT_RDWR);
54 sk_release_kernel(sock->sk);
55 }
56 *sockp = NULL;
57 return err;
58}
59EXPORT_SYMBOL(udp_sock_create4);
60
61void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
62 struct udp_tunnel_sock_cfg *cfg)
63{
64 struct sock *sk = sock->sk;
65
66
67 inet_sk(sk)->mc_loop = 0;
68
69
70 inet_inc_convert_csum(sk);
71
72 rcu_assign_sk_user_data(sk, cfg->sk_user_data);
73
74 udp_sk(sk)->encap_type = cfg->encap_type;
75 udp_sk(sk)->encap_rcv = cfg->encap_rcv;
76 udp_sk(sk)->encap_err_lookup = cfg->encap_err_lookup;
77 udp_sk(sk)->encap_destroy = cfg->encap_destroy;
78 udp_sk(sk)->gro_receive = cfg->gro_receive;
79 udp_sk(sk)->gro_complete = cfg->gro_complete;
80
81 udp_tunnel_encap_enable(sock);
82}
83EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
84
85static void __udp_tunnel_push_rx_port(struct net_device *dev,
86 struct udp_tunnel_info *ti)
87{
88 if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
89 return;
90
91 if (get_ndo_ext(dev->netdev_ops, ndo_udp_tunnel_add)) {
92 get_ndo_ext(dev->netdev_ops, ndo_udp_tunnel_add)(dev, ti);
93 return;
94 }
95
96 switch (ti->type) {
97 case UDP_TUNNEL_TYPE_VXLAN:
98 if (!dev->netdev_ops->ndo_add_vxlan_port)
99 break;
100
101 dev->netdev_ops->ndo_add_vxlan_port(dev,
102 ti->sa_family,
103 ti->port);
104 break;
105 case UDP_TUNNEL_TYPE_GENEVE:
106 if (!dev->netdev_ops->ndo_add_geneve_port)
107 break;
108
109 dev->netdev_ops->ndo_add_geneve_port(dev,
110 ti->sa_family,
111 ti->port);
112 break;
113 default:
114 break;
115 }
116}
117
118void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
119 unsigned short type)
120{
121 struct sock *sk = sock->sk;
122 struct udp_tunnel_info ti;
123
124 ti.type = type;
125 ti.sa_family = sk->sk_family;
126 ti.port = inet_sk(sk)->inet_sport;
127
128 __udp_tunnel_push_rx_port(dev, &ti);
129}
130EXPORT_SYMBOL_GPL(udp_tunnel_push_rx_port);
131
132void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
133 unsigned short type)
134{
135 struct sock *sk = sock->sk;
136 struct udp_tunnel_info ti;
137
138 ti.type = type;
139 ti.sa_family = sk->sk_family;
140 ti.port = inet_sk(sk)->inet_sport;
141
142 __udp_tunnel_pull_rx_port(dev, &ti);
143}
144EXPORT_SYMBOL_GPL(udp_tunnel_drop_rx_port);
145
146
147void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type)
148{
149 struct sock *sk = sock->sk;
150 struct net *net = sock_net(sk);
151 struct udp_tunnel_info ti;
152 struct net_device *dev;
153
154 ti.type = type;
155 ti.sa_family = sk->sk_family;
156 ti.port = inet_sk(sk)->inet_sport;
157
158 rcu_read_lock();
159 for_each_netdev_rcu(net, dev)
160 __udp_tunnel_push_rx_port(dev, &ti);
161 rcu_read_unlock();
162}
163EXPORT_SYMBOL_GPL(udp_tunnel_notify_add_rx_port);
164
165static void __udp_tunnel_pull_rx_port(struct net_device *dev,
166 struct udp_tunnel_info *ti)
167{
168 if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT))
169 return;
170
171 if (get_ndo_ext(dev->netdev_ops, ndo_udp_tunnel_del)) {
172 get_ndo_ext(dev->netdev_ops, ndo_udp_tunnel_del)(dev, ti);
173 return;
174 }
175
176 switch (ti->type) {
177 case UDP_TUNNEL_TYPE_VXLAN:
178 if (!dev->netdev_ops->ndo_del_vxlan_port)
179 break;
180
181 dev->netdev_ops->ndo_del_vxlan_port(dev,
182 ti->sa_family,
183 ti->port);
184 break;
185 case UDP_TUNNEL_TYPE_GENEVE:
186 if (!dev->netdev_ops->ndo_del_geneve_port)
187 break;
188
189 dev->netdev_ops->ndo_del_geneve_port(dev,
190 ti->sa_family,
191 ti->port);
192 break;
193 default:
194 break;
195 }
196}
197
198
199void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type)
200{
201 struct sock *sk = sock->sk;
202 struct net *net = sock_net(sk);
203 struct udp_tunnel_info ti;
204 struct net_device *dev;
205
206 ti.type = type;
207 ti.sa_family = sk->sk_family;
208 ti.port = inet_sk(sk)->inet_sport;
209
210 rcu_read_lock();
211 for_each_netdev_rcu(net, dev)
212 __udp_tunnel_pull_rx_port(dev, &ti);
213 rcu_read_unlock();
214}
215EXPORT_SYMBOL_GPL(udp_tunnel_notify_del_rx_port);
216
217void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
218 __be32 src, __be32 dst, __u8 tos, __u8 ttl,
219 __be16 df, __be16 src_port, __be16 dst_port,
220 bool xnet, bool nocheck)
221{
222 struct udphdr *uh;
223
224 __skb_push(skb, sizeof(*uh));
225 skb_reset_transport_header(skb);
226 uh = udp_hdr(skb);
227
228 uh->dest = dst_port;
229 uh->source = src_port;
230 uh->len = htons(skb->len);
231
232 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
233
234 udp_set_csum(nocheck, skb, src, dst, skb->len);
235
236 iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, xnet);
237}
238EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
239
240void udp_tunnel_sock_release(struct socket *sock)
241{
242 rcu_assign_sk_user_data(sock->sk, NULL);
243 kernel_sock_shutdown(sock, SHUT_RDWR);
244 sk_release_kernel(sock->sk);
245}
246EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
247
248struct metadata_dst *udp_tun_rx_dst(struct sk_buff *skb, unsigned short family,
249 __be16 flags, __be64 tunnel_id, int md_size)
250{
251 struct metadata_dst *tun_dst;
252 struct ip_tunnel_info *info;
253
254 if (family == AF_INET)
255 tun_dst = ip_tun_rx_dst(skb, flags, tunnel_id, md_size);
256 else
257 tun_dst = ipv6_tun_rx_dst(skb, flags, tunnel_id, md_size);
258 if (!tun_dst)
259 return NULL;
260
261 info = &tun_dst->u.tun_info;
262 info->key.tp_src = udp_hdr(skb)->source;
263 info->key.tp_dst = udp_hdr(skb)->dest;
264 if (udp_hdr(skb)->check)
265 info->key.tun_flags |= TUNNEL_CSUM;
266 return tun_dst;
267}
268EXPORT_SYMBOL_GPL(udp_tun_rx_dst);
269
270MODULE_LICENSE("GPL");
271