Blame view

net/ipv4/udp.c 77.9 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
   *		interface as the means of communication with the user level.
   *
   *		The User Datagram Protocol (UDP).
   *
02c30a84e   Jesper Juhl   [PATCH] update Ro...
9
   * Authors:	Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
   *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
113aa838e   Alan Cox   net: Rationalise ...
12
   *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
   *		Hirokazu Takahashi, <taka@valinux.co.jp>
   *
   * Fixes:
   *		Alan Cox	:	verify_area() calls
   *		Alan Cox	: 	stopped close while in use off icmp
   *					messages. Not a fix but a botch that
   *					for udp at least is 'valid'.
   *		Alan Cox	:	Fixed icmp handling properly
   *		Alan Cox	: 	Correct error for oversized datagrams
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
22
23
   *		Alan Cox	:	Tidied select() semantics.
   *		Alan Cox	:	udp_err() fixed properly, also now
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
   *					select and read wake correctly on errors
   *		Alan Cox	:	udp_send verify_area moved to avoid mem leak
   *		Alan Cox	:	UDP can count its memory
   *		Alan Cox	:	send to an unknown connection causes
   *					an ECONNREFUSED off the icmp, but
   *					does NOT close.
   *		Alan Cox	:	Switched to new sk_buff handlers. No more backlog!
   *		Alan Cox	:	Using generic datagram code. Even smaller and the PEEK
   *					bug no longer crashes it.
   *		Fred Van Kempen	: 	Net2e support for sk->broadcast.
   *		Alan Cox	:	Uses skb_free_datagram
   *		Alan Cox	:	Added get/set sockopt support.
   *		Alan Cox	:	Broadcasting without option set returns EACCES.
   *		Alan Cox	:	No wakeup calls. Instead we now use the callbacks.
   *		Alan Cox	:	Use ip_tos and ip_ttl
   *		Alan Cox	:	SNMP Mibs
   *		Alan Cox	:	MSG_DONTROUTE, and 0.0.0.0 support.
   *		Matt Dillon	:	UDP length checks.
   *		Alan Cox	:	Smarter af_inet used properly.
   *		Alan Cox	:	Use new kernel side addressing.
   *		Alan Cox	:	Incorrect return on truncated datagram receive.
   *	Arnt Gulbrandsen 	:	New udp_send and stuff
   *		Alan Cox	:	Cache last socket
   *		Alan Cox	:	Route cache
   *		Jon Peatfield	:	Minor efficiency fix to sendto().
   *		Mike Shaver	:	RFC1122 checks.
   *		Alan Cox	:	Nonblocking error fix.
   *	Willy Konynenberg	:	Transparent proxying support.
   *		Mike McLagan	:	Routing by source
   *		David S. Miller	:	New socket lookup architecture.
   *					Last socket cache retained as it
   *					does have a high hit rate.
   *		Olaf Kirch	:	Don't linearise iovec on sendmsg.
   *		Andi Kleen	:	Some cleanups, cache destination entry
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
58
   *					for connect.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
65
66
67
68
69
70
71
   *	Vitaly E. Lavrov	:	Transparent proxy revived after year coma.
   *		Melvin Smith	:	Check msg_name not msg_namelen in sendto(),
   *					return ENOTCONN for unconnected sockets (POSIX)
   *		Janos Farkas	:	don't deliver multi/broadcasts to a different
   *					bound-to-device socket
   *	Hirokazu Takahashi	:	HW checksumming for outgoing UDP
   *					datagrams.
   *	Hirokazu Takahashi	:	sendfile() on UDP works now.
   *		Arnaldo C. Melo :	convert /proc/net/udp to seq_file
   *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
   *	Alexey Kuznetsov:		allow both IPv4 and IPv6 sockets to bind
   *					a single port at the same time.
   *	Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
342f0234c   James Chapman   [UDP]: Introduce ...
72
   *	James Chapman		:	Add L2TP encapsulation type.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
   */
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
74

afd465030   Joe Perches   net: ipv4: Standa...
75
  #define pr_fmt(fmt) "UDP: " fmt
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
76
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  #include <asm/ioctls.h>
57c8a661d   Mike Rapoport   mm: remove includ...
78
  #include <linux/memblock.h>
8203efb3c   Eric Dumazet   udp: calculate ud...
79
80
  #include <linux/highmem.h>
  #include <linux/swap.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
83
84
85
  #include <linux/types.h>
  #include <linux/fcntl.h>
  #include <linux/module.h>
  #include <linux/socket.h>
  #include <linux/sockios.h>
14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
86
  #include <linux/igmp.h>
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
87
  #include <linux/inetdevice.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
  #include <linux/in.h>
  #include <linux/errno.h>
  #include <linux/timer.h>
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  #include <linux/inet.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  #include <linux/netdevice.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
94
  #include <linux/slab.h>
c752f0739   Arnaldo Carvalho de Melo   [TCP]: Move the t...
95
  #include <net/tcp_states.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
  #include <linux/skbuff.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
99
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  #include <net/icmp.h>
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
101
  #include <net/inet_hashtables.h>
e7cc08245   Stefano Brivio   udp: Support for ...
102
  #include <net/ip_tunnels.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  #include <net/route.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
  #include <net/checksum.h>
  #include <net/xfrm.h>
296f7ea75   Satoru Moriya   udp: add tracepoi...
106
  #include <trace/events/udp.h>
447167bf5   Eric Dumazet   udp: intoduce udp...
107
  #include <linux/static_key.h>
22911fc58   Eric Dumazet   net: skb_free_dat...
108
  #include <trace/events/skb.h>
076bb0c82   Eliezer Tamir   net: rename inclu...
109
  #include <net/busy_poll.h>
ba4e58eca   Gerrit Renker   [NET]: Supporting...
110
  #include "udp_impl.h"
e32ea7e74   Craig Gallek   soreuseport: fast...
111
  #include <net/sock_reuseport.h>
217375a0c   Eric Dumazet   udp: include addr...
112
  #include <net/addrconf.h>
60fb9567b   Paolo Abeni   udp: implement co...
113
  #include <net/udp_tunnel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114

f86dcc5aa   Eric Dumazet   udp: dynamically ...
115
  struct udp_table udp_table __read_mostly;
645ca708f   Eric Dumazet   udp: introduce st...
116
  EXPORT_SYMBOL(udp_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117

8d987e5c7   Eric Dumazet   net: avoid limits...
118
  long sysctl_udp_mem[3] __read_mostly;
95766fff6   Hideo Aoki   [UDP]: Add memory...
119
  EXPORT_SYMBOL(sysctl_udp_mem);
c482c5685   Eric Dumazet   udp: cleanups
120

8d987e5c7   Eric Dumazet   net: avoid limits...
121
  atomic_long_t udp_memory_allocated;
95766fff6   Hideo Aoki   [UDP]: Add memory...
122
  EXPORT_SYMBOL(udp_memory_allocated);
f86dcc5aa   Eric Dumazet   udp: dynamically ...
123
124
  #define MAX_UDP_PORTS 65536
  #define PORTS_PER_CHAIN (MAX_UDP_PORTS / UDP_HTABLE_SIZE_MIN)
98322f22e   Eric Dumazet   udp: optimize bin...
125

f24d43c07   Eric Dumazet   udp: complete por...
126
  static int udp_lib_lport_inuse(struct net *net, __u16 num,
645ca708f   Eric Dumazet   udp: introduce st...
127
  			       const struct udp_hslot *hslot,
98322f22e   Eric Dumazet   udp: optimize bin...
128
  			       unsigned long *bitmap,
fe38d2a1c   Josef Bacik   inet: collapse ip...
129
  			       struct sock *sk, unsigned int log)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  {
f24d43c07   Eric Dumazet   udp: complete por...
131
  	struct sock *sk2;
ba418fa35   Tom Herbert   soreuseport: UDP/...
132
  	kuid_t uid = sock_i_uid(sk);
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
133

ca065d0cf   Eric Dumazet   udp: no longer us...
134
  	sk_for_each(sk2, &hslot->head) {
9d4fb27db   Joe Perches   net/ipv4: Move &&...
135
136
  		if (net_eq(sock_net(sk2), net) &&
  		    sk2 != sk &&
d4cada4ae   Eric Dumazet   udp: split sk_has...
137
  		    (bitmap || udp_sk(sk2)->udp_port_hash == num) &&
9d4fb27db   Joe Perches   net/ipv4: Move &&...
138
139
140
  		    (!sk2->sk_reuse || !sk->sk_reuse) &&
  		    (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
  		     sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
fe38d2a1c   Josef Bacik   inet: collapse ip...
141
  		    inet_rcv_saddr_equal(sk, sk2, true)) {
df560056d   Eric Garver   udp: inuse checks...
142
143
144
145
146
147
148
149
150
151
152
  			if (sk2->sk_reuseport && sk->sk_reuseport &&
  			    !rcu_access_pointer(sk->sk_reuseport_cb) &&
  			    uid_eq(uid, sock_i_uid(sk2))) {
  				if (!bitmap)
  					return 0;
  			} else {
  				if (!bitmap)
  					return 1;
  				__set_bit(udp_sk(sk2)->udp_port_hash >> log,
  					  bitmap);
  			}
98322f22e   Eric Dumazet   udp: optimize bin...
153
  		}
4243cdc2c   Joe Perches   udp: Neaten funct...
154
  	}
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
155
156
  	return 0;
  }
30fff9231   Eric Dumazet   udp: bind() optim...
157
158
159
160
161
  /*
   * Note: we still hold spinlock of primary hash chain, so no other writer
   * can insert/delete a socket with local_port == num
   */
  static int udp_lib_lport_inuse2(struct net *net, __u16 num,
4243cdc2c   Joe Perches   udp: Neaten funct...
162
  				struct udp_hslot *hslot2,
fe38d2a1c   Josef Bacik   inet: collapse ip...
163
  				struct sock *sk)
30fff9231   Eric Dumazet   udp: bind() optim...
164
165
  {
  	struct sock *sk2;
ba418fa35   Tom Herbert   soreuseport: UDP/...
166
  	kuid_t uid = sock_i_uid(sk);
30fff9231   Eric Dumazet   udp: bind() optim...
167
168
169
  	int res = 0;
  
  	spin_lock(&hslot2->lock);
ca065d0cf   Eric Dumazet   udp: no longer us...
170
  	udp_portaddr_for_each_entry(sk2, &hslot2->head) {
9d4fb27db   Joe Perches   net/ipv4: Move &&...
171
172
173
174
175
176
  		if (net_eq(sock_net(sk2), net) &&
  		    sk2 != sk &&
  		    (udp_sk(sk2)->udp_port_hash == num) &&
  		    (!sk2->sk_reuse || !sk->sk_reuse) &&
  		    (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
  		     sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
fe38d2a1c   Josef Bacik   inet: collapse ip...
177
  		    inet_rcv_saddr_equal(sk, sk2, true)) {
df560056d   Eric Garver   udp: inuse checks...
178
179
180
181
182
183
184
  			if (sk2->sk_reuseport && sk->sk_reuseport &&
  			    !rcu_access_pointer(sk->sk_reuseport_cb) &&
  			    uid_eq(uid, sock_i_uid(sk2))) {
  				res = 0;
  			} else {
  				res = 1;
  			}
30fff9231   Eric Dumazet   udp: bind() optim...
185
186
  			break;
  		}
4243cdc2c   Joe Perches   udp: Neaten funct...
187
  	}
30fff9231   Eric Dumazet   udp: bind() optim...
188
189
190
  	spin_unlock(&hslot2->lock);
  	return res;
  }
fe38d2a1c   Josef Bacik   inet: collapse ip...
191
  static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
e32ea7e74   Craig Gallek   soreuseport: fast...
192
193
  {
  	struct net *net = sock_net(sk);
e32ea7e74   Craig Gallek   soreuseport: fast...
194
195
  	kuid_t uid = sock_i_uid(sk);
  	struct sock *sk2;
ca065d0cf   Eric Dumazet   udp: no longer us...
196
  	sk_for_each(sk2, &hslot->head) {
e32ea7e74   Craig Gallek   soreuseport: fast...
197
198
199
200
201
202
203
  		if (net_eq(sock_net(sk2), net) &&
  		    sk2 != sk &&
  		    sk2->sk_family == sk->sk_family &&
  		    ipv6_only_sock(sk2) == ipv6_only_sock(sk) &&
  		    (udp_sk(sk2)->udp_port_hash == udp_sk(sk)->udp_port_hash) &&
  		    (sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
  		    sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) &&
fe38d2a1c   Josef Bacik   inet: collapse ip...
204
  		    inet_rcv_saddr_equal(sk, sk2, false)) {
2dbb9b9e6   Martin KaFai Lau   bpf: Introduce BP...
205
206
  			return reuseport_add_sock(sk, sk2,
  						  inet_rcv_saddr_any(sk));
e32ea7e74   Craig Gallek   soreuseport: fast...
207
208
  		}
  	}
2dbb9b9e6   Martin KaFai Lau   bpf: Introduce BP...
209
  	return reuseport_alloc(sk, inet_rcv_saddr_any(sk));
e32ea7e74   Craig Gallek   soreuseport: fast...
210
  }
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
211
  /**
6ba5a3c52   Pavel Emelyanov   [UDP]: Make full ...
212
   *  udp_lib_get_port  -  UDP/-Lite port lookup for IPv4 and IPv6
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
213
214
215
   *
   *  @sk:          socket struct in question
   *  @snum:        port number to look up
25985edce   Lucas De Marchi   Fix common misspe...
216
   *  @hash2_nulladdr: AF-dependent hash value in secondary hash chains,
30fff9231   Eric Dumazet   udp: bind() optim...
217
   *                   with NULL address
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
218
   */
6ba5a3c52   Pavel Emelyanov   [UDP]: Make full ...
219
  int udp_lib_get_port(struct sock *sk, unsigned short snum,
30fff9231   Eric Dumazet   udp: bind() optim...
220
  		     unsigned int hash2_nulladdr)
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
221
  {
512615b6b   Eric Dumazet   udp: secondary ha...
222
  	struct udp_hslot *hslot, *hslot2;
645ca708f   Eric Dumazet   udp: introduce st...
223
  	struct udp_table *udptable = sk->sk_prot->h.udp_table;
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
224
  	int    error = 1;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
225
  	struct net *net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226

32c1da708   Stephen Hemminger   [UDP]: Randomize ...
227
  	if (!snum) {
9088c5609   Eric Dumazet   udp: Improve port...
228
  		int low, high, remaining;
95c961747   Eric Dumazet   net: cleanup unsi...
229
  		unsigned int rand;
98322f22e   Eric Dumazet   udp: optimize bin...
230
231
  		unsigned short first, last;
  		DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
32c1da708   Stephen Hemminger   [UDP]: Randomize ...
232

0bbf87d85   Eric W. Biederman   net ipv4: Convert...
233
  		inet_get_local_port_range(net, &low, &high);
a25de534f   Anton Arapov   [INET]: Justifica...
234
  		remaining = (high - low) + 1;
227b60f51   Stephen Hemminger   [INET]: local por...
235

63862b5be   Aruna-Hewapathirane   net: replace macr...
236
  		rand = prandom_u32();
8fc54f689   Daniel Borkmann   net: use reciproc...
237
  		first = reciprocal_scale(rand, remaining) + low;
98322f22e   Eric Dumazet   udp: optimize bin...
238
239
240
  		/*
  		 * force rand to be an odd multiple of UDP_HTABLE_SIZE
  		 */
f86dcc5aa   Eric Dumazet   udp: dynamically ...
241
  		rand = (rand | 1) * (udptable->mask + 1);
5781b2356   Eric Dumazet   udp: udp_lib_get_...
242
243
  		last = first + udptable->mask + 1;
  		do {
f86dcc5aa   Eric Dumazet   udp: dynamically ...
244
  			hslot = udp_hashslot(udptable, net, first);
98322f22e   Eric Dumazet   udp: optimize bin...
245
  			bitmap_zero(bitmap, PORTS_PER_CHAIN);
645ca708f   Eric Dumazet   udp: introduce st...
246
  			spin_lock_bh(&hslot->lock);
98322f22e   Eric Dumazet   udp: optimize bin...
247
  			udp_lib_lport_inuse(net, snum, hslot, bitmap, sk,
fe38d2a1c   Josef Bacik   inet: collapse ip...
248
  					    udptable->log);
98322f22e   Eric Dumazet   udp: optimize bin...
249
250
251
252
253
254
255
  
  			snum = first;
  			/*
  			 * Iterate on all possible values of snum for this hash.
  			 * Using steps of an odd multiple of UDP_HTABLE_SIZE
  			 * give us randomization and full range coverage.
  			 */
9088c5609   Eric Dumazet   udp: Improve port...
256
  			do {
98322f22e   Eric Dumazet   udp: optimize bin...
257
  				if (low <= snum && snum <= high &&
e3826f1e9   Amerigo Wang   net: reserve port...
258
  				    !test_bit(snum >> udptable->log, bitmap) &&
122ff243f   WANG Cong   ipv4: make ip_loc...
259
  				    !inet_is_local_reserved_port(net, snum))
98322f22e   Eric Dumazet   udp: optimize bin...
260
261
262
263
  					goto found;
  				snum += rand;
  			} while (snum != first);
  			spin_unlock_bh(&hslot->lock);
df560056d   Eric Garver   udp: inuse checks...
264
  			cond_resched();
5781b2356   Eric Dumazet   udp: udp_lib_get_...
265
  		} while (++first != last);
98322f22e   Eric Dumazet   udp: optimize bin...
266
  		goto fail;
645ca708f   Eric Dumazet   udp: introduce st...
267
  	} else {
f86dcc5aa   Eric Dumazet   udp: dynamically ...
268
  		hslot = udp_hashslot(udptable, net, snum);
645ca708f   Eric Dumazet   udp: introduce st...
269
  		spin_lock_bh(&hslot->lock);
30fff9231   Eric Dumazet   udp: bind() optim...
270
271
272
273
274
275
276
277
278
279
  		if (hslot->count > 10) {
  			int exist;
  			unsigned int slot2 = udp_sk(sk)->udp_portaddr_hash ^ snum;
  
  			slot2          &= udptable->mask;
  			hash2_nulladdr &= udptable->mask;
  
  			hslot2 = udp_hashslot2(udptable, slot2);
  			if (hslot->count < hslot2->count)
  				goto scan_primary_hash;
fe38d2a1c   Josef Bacik   inet: collapse ip...
280
  			exist = udp_lib_lport_inuse2(net, snum, hslot2, sk);
30fff9231   Eric Dumazet   udp: bind() optim...
281
282
283
  			if (!exist && (hash2_nulladdr != slot2)) {
  				hslot2 = udp_hashslot2(udptable, hash2_nulladdr);
  				exist = udp_lib_lport_inuse2(net, snum, hslot2,
fe38d2a1c   Josef Bacik   inet: collapse ip...
284
  							     sk);
30fff9231   Eric Dumazet   udp: bind() optim...
285
286
287
288
289
290
291
  			}
  			if (exist)
  				goto fail_unlock;
  			else
  				goto found;
  		}
  scan_primary_hash:
fe38d2a1c   Josef Bacik   inet: collapse ip...
292
  		if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk, 0))
645ca708f   Eric Dumazet   udp: introduce st...
293
294
  			goto fail_unlock;
  	}
98322f22e   Eric Dumazet   udp: optimize bin...
295
  found:
c720c7e83   Eric Dumazet   inet: rename some...
296
  	inet_sk(sk)->inet_num = snum;
d4cada4ae   Eric Dumazet   udp: split sk_has...
297
298
  	udp_sk(sk)->udp_port_hash = snum;
  	udp_sk(sk)->udp_portaddr_hash ^= snum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  	if (sk_unhashed(sk)) {
e32ea7e74   Craig Gallek   soreuseport: fast...
300
  		if (sk->sk_reuseport &&
fe38d2a1c   Josef Bacik   inet: collapse ip...
301
  		    udp_reuseport_add_sock(sk, hslot)) {
e32ea7e74   Craig Gallek   soreuseport: fast...
302
303
304
305
306
  			inet_sk(sk)->inet_num = 0;
  			udp_sk(sk)->udp_port_hash = 0;
  			udp_sk(sk)->udp_portaddr_hash ^= snum;
  			goto fail_unlock;
  		}
ca065d0cf   Eric Dumazet   udp: no longer us...
307
  		sk_add_node_rcu(sk, &hslot->head);
fdcc8aa95   Eric Dumazet   udp: add a counte...
308
  		hslot->count++;
c29a0bc4d   Pavel Emelyanov   [SOCK][NETNS]: Ad...
309
  		sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
512615b6b   Eric Dumazet   udp: secondary ha...
310
311
312
  
  		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
  		spin_lock(&hslot2->lock);
d894ba18d   Craig Gallek   soreuseport: fix ...
313
  		if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
1602f49b5   David S. Miller   Merge git://git.k...
314
315
316
  		    sk->sk_family == AF_INET6)
  			hlist_add_tail_rcu(&udp_sk(sk)->udp_portaddr_node,
  					   &hslot2->head);
d894ba18d   Craig Gallek   soreuseport: fix ...
317
  		else
1602f49b5   David S. Miller   Merge git://git.k...
318
319
  			hlist_add_head_rcu(&udp_sk(sk)->udp_portaddr_node,
  					   &hslot2->head);
512615b6b   Eric Dumazet   udp: secondary ha...
320
321
  		hslot2->count++;
  		spin_unlock(&hslot2->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  	}
ca065d0cf   Eric Dumazet   udp: no longer us...
323
  	sock_set_flag(sk, SOCK_RCU_FREE);
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
324
  	error = 0;
645ca708f   Eric Dumazet   udp: introduce st...
325
326
  fail_unlock:
  	spin_unlock_bh(&hslot->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  fail:
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
328
329
  	return error;
  }
c482c5685   Eric Dumazet   udp: cleanups
330
  EXPORT_SYMBOL(udp_lib_get_port);
25030a7f9   Gerrit Renker   [UDP]: Unify UDPv...
331

6ba5a3c52   Pavel Emelyanov   [UDP]: Make full ...
332
  int udp_v4_get_port(struct sock *sk, unsigned short snum)
db8dac20d   David S. Miller   [UDP]: Revert udp...
333
  {
30fff9231   Eric Dumazet   udp: bind() optim...
334
  	unsigned int hash2_nulladdr =
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
335
  		ipv4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum);
30fff9231   Eric Dumazet   udp: bind() optim...
336
  	unsigned int hash2_partial =
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
337
  		ipv4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0);
30fff9231   Eric Dumazet   udp: bind() optim...
338

d4cada4ae   Eric Dumazet   udp: split sk_has...
339
  	/* precompute partial secondary hash */
30fff9231   Eric Dumazet   udp: bind() optim...
340
  	udp_sk(sk)->udp_portaddr_hash = hash2_partial;
fe38d2a1c   Josef Bacik   inet: collapse ip...
341
  	return udp_lib_get_port(sk, snum, hash2_nulladdr);
db8dac20d   David S. Miller   [UDP]: Revert udp...
342
  }
d1e37288c   Su, Xuemin   udp reuseport: fi...
343
344
  static int compute_score(struct sock *sk, struct net *net,
  			 __be32 saddr, __be16 sport,
fb74c2773   David Ahern   net: ipv4: add se...
345
  			 __be32 daddr, unsigned short hnum,
735453730   Tim Beale   udp: Remove unuse...
346
  			 int dif, int sdif)
645ca708f   Eric Dumazet   udp: introduce st...
347
  {
60c04aecd   Joe Perches   udp: Neaten and r...
348
349
  	int score;
  	struct inet_sock *inet;
6da5b0f02   Mike Manning   net: ensure unbou...
350
  	bool dev_match;
645ca708f   Eric Dumazet   udp: introduce st...
351

60c04aecd   Joe Perches   udp: Neaten and r...
352
353
354
355
  	if (!net_eq(sock_net(sk), net) ||
  	    udp_sk(sk)->udp_port_hash != hnum ||
  	    ipv6_only_sock(sk))
  		return -1;
645ca708f   Eric Dumazet   udp: introduce st...
356

4cdeeee92   Peter Oskolkov   net: udp: prefer ...
357
358
  	if (sk->sk_rcv_saddr != daddr)
  		return -1;
60c04aecd   Joe Perches   udp: Neaten and r...
359

4cdeeee92   Peter Oskolkov   net: udp: prefer ...
360
  	score = (sk->sk_family == PF_INET) ? 2 : 1;
60c04aecd   Joe Perches   udp: Neaten and r...
361

4cdeeee92   Peter Oskolkov   net: udp: prefer ...
362
  	inet = inet_sk(sk);
60c04aecd   Joe Perches   udp: Neaten and r...
363
364
365
366
367
368
369
370
371
372
373
  	if (inet->inet_daddr) {
  		if (inet->inet_daddr != saddr)
  			return -1;
  		score += 4;
  	}
  
  	if (inet->inet_dport) {
  		if (inet->inet_dport != sport)
  			return -1;
  		score += 4;
  	}
6da5b0f02   Mike Manning   net: ensure unbou...
374
375
376
377
378
  	dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
  					dif, sdif);
  	if (!dev_match)
  		return -1;
  	score += 4;
fb74c2773   David Ahern   net: ipv4: add se...
379

7170a9777   Eric Dumazet   net: annotate acc...
380
  	if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
70da268b5   Eric Dumazet   net: SO_INCOMING_...
381
  		score++;
645ca708f   Eric Dumazet   udp: introduce st...
382
383
  	return score;
  }
6eada0110   Eric Dumazet   netns: constify n...
384
385
386
  static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
  		       const __u16 lport, const __be32 faddr,
  		       const __be16 fport)
65cd8033f   Hannes Frederic Sowa   ipv4: split inet_...
387
  {
1bbdceef1   Hannes Frederic Sowa   inet: convert ine...
388
389
390
  	static u32 udp_ehash_secret __read_mostly;
  
  	net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret));
65cd8033f   Hannes Frederic Sowa   ipv4: split inet_...
391
  	return __inet_ehashfn(laddr, lport, faddr, fport,
1bbdceef1   Hannes Frederic Sowa   inet: convert ine...
392
  			      udp_ehash_secret + net_hash_mix(net));
65cd8033f   Hannes Frederic Sowa   ipv4: split inet_...
393
  }
d1e37288c   Su, Xuemin   udp reuseport: fi...
394
  /* called with rcu_read_lock() */
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
395
  static struct sock *udp4_lib_lookup2(struct net *net,
fb74c2773   David Ahern   net: ipv4: add se...
396
397
  				     __be32 saddr, __be16 sport,
  				     __be32 daddr, unsigned int hnum,
735453730   Tim Beale   udp: Remove unuse...
398
  				     int dif, int sdif,
fb74c2773   David Ahern   net: ipv4: add se...
399
400
  				     struct udp_hslot *hslot2,
  				     struct sk_buff *skb)
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
401
402
  {
  	struct sock *sk, *result;
e94a62f50   Paolo Abeni   net/reuseport: dr...
403
  	int score, badness;
ba418fa35   Tom Herbert   soreuseport: UDP/...
404
  	u32 hash = 0;
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
405

5051ebd27   Eric Dumazet   ipv4: udp: optimi...
406
  	result = NULL;
ba418fa35   Tom Herbert   soreuseport: UDP/...
407
  	badness = 0;
ca065d0cf   Eric Dumazet   udp: no longer us...
408
  	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
d1e37288c   Su, Xuemin   udp reuseport: fi...
409
  		score = compute_score(sk, net, saddr, sport,
735453730   Tim Beale   udp: Remove unuse...
410
  				      daddr, hnum, dif, sdif);
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
411
  		if (score > badness) {
acdcecc61   Willem de Bruijn   udp: correct reus...
412
413
  			if (sk->sk_reuseport &&
  			    sk->sk_state != TCP_ESTABLISHED) {
65cd8033f   Hannes Frederic Sowa   ipv4: split inet_...
414
415
  				hash = udp_ehashfn(net, daddr, hnum,
  						   saddr, sport);
ca065d0cf   Eric Dumazet   udp: no longer us...
416
  				result = reuseport_select_sock(sk, hash, skb,
ed0dfffd7   Eric Dumazet   udp: fix potentia...
417
  							sizeof(struct udphdr));
acdcecc61   Willem de Bruijn   udp: correct reus...
418
  				if (result && !reuseport_has_conns(sk, false))
ca065d0cf   Eric Dumazet   udp: no longer us...
419
  					return result;
ba418fa35   Tom Herbert   soreuseport: UDP/...
420
  			}
ca065d0cf   Eric Dumazet   udp: no longer us...
421
422
  			badness = score;
  			result = sk;
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
423
424
  		}
  	}
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
425
426
  	return result;
  }
db8dac20d   David S. Miller   [UDP]: Revert udp...
427
428
429
  /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
   * harder than this. -DaveM
   */
fce823381   Pavel Emelyanov   udp: Export code ...
430
  struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
fb74c2773   David Ahern   net: ipv4: add se...
431
432
  		__be16 sport, __be32 daddr, __be16 dport, int dif,
  		int sdif, struct udp_table *udptable, struct sk_buff *skb)
db8dac20d   David S. Miller   [UDP]: Revert udp...
433
  {
4cdeeee92   Peter Oskolkov   net: udp: prefer ...
434
  	struct sock *result;
db8dac20d   David S. Miller   [UDP]: Revert udp...
435
  	unsigned short hnum = ntohs(dport);
4cdeeee92   Peter Oskolkov   net: udp: prefer ...
436
437
  	unsigned int hash2, slot2;
  	struct udp_hslot *hslot2;
645ca708f   Eric Dumazet   udp: introduce st...
438

4cdeeee92   Peter Oskolkov   net: udp: prefer ...
439
440
441
442
443
444
  	hash2 = ipv4_portaddr_hash(net, daddr, hnum);
  	slot2 = hash2 & udptable->mask;
  	hslot2 = &udptable->hash2[slot2];
  
  	result = udp4_lib_lookup2(net, saddr, sport,
  				  daddr, hnum, dif, sdif,
735453730   Tim Beale   udp: Remove unuse...
445
  				  hslot2, skb);
4cdeeee92   Peter Oskolkov   net: udp: prefer ...
446
447
  	if (!result) {
  		hash2 = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
448
449
  		slot2 = hash2 & udptable->mask;
  		hslot2 = &udptable->hash2[slot2];
5051ebd27   Eric Dumazet   ipv4: udp: optimi...
450
451
  
  		result = udp4_lib_lookup2(net, saddr, sport,
4cdeeee92   Peter Oskolkov   net: udp: prefer ...
452
  					  htonl(INADDR_ANY), hnum, dif, sdif,
735453730   Tim Beale   udp: Remove unuse...
453
  					  hslot2, skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
454
  	}
88e235b80   Enrico Weigelt   net: ipv4: drop u...
455
  	if (IS_ERR(result))
4cdeeee92   Peter Oskolkov   net: udp: prefer ...
456
  		return NULL;
db8dac20d   David S. Miller   [UDP]: Revert udp...
457
458
  	return result;
  }
fce823381   Pavel Emelyanov   udp: Export code ...
459
  EXPORT_SYMBOL_GPL(__udp4_lib_lookup);
db8dac20d   David S. Miller   [UDP]: Revert udp...
460

607c4aaf0   KOVACS Krisztian   inet: Add udplib_...
461
462
  static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
  						 __be16 sport, __be16 dport,
645ca708f   Eric Dumazet   udp: introduce st...
463
  						 struct udp_table *udptable)
607c4aaf0   KOVACS Krisztian   inet: Add udplib_...
464
465
  {
  	const struct iphdr *iph = ip_hdr(skb);
ed7cbbce5   Alexander Duyck   udp: Resolve NULL...
466
  	return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
8afdd99a1   Eric Dumazet   udp: ipv4: fix an...
467
  				 iph->daddr, dport, inet_iif(skb),
fb74c2773   David Ahern   net: ipv4: add se...
468
  				 inet_sdif(skb), udptable, skb);
607c4aaf0   KOVACS Krisztian   inet: Add udplib_...
469
  }
63058308c   Tom Herbert   udp: Add udp6_lib...
470
471
472
  struct sock *udp4_lib_lookup_skb(struct sk_buff *skb,
  				 __be16 sport, __be16 dport)
  {
257a525fe   Martin KaFai Lau   bpf: udp: Avoid c...
473
474
475
476
477
  	const struct iphdr *iph = ip_hdr(skb);
  
  	return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
  				 iph->daddr, dport, inet_iif(skb),
  				 inet_sdif(skb), &udp_table, NULL);
63058308c   Tom Herbert   udp: Add udp6_lib...
478
479
  }
  EXPORT_SYMBOL_GPL(udp4_lib_lookup_skb);
ca065d0cf   Eric Dumazet   udp: no longer us...
480
481
482
  /* Must be called under rcu_read_lock().
   * Does increment socket refcount.
   */
6e86000c2   Arnd Bergmann   netfilter: provid...
483
  #if IS_ENABLED(CONFIG_NF_TPROXY_IPV4) || IS_ENABLED(CONFIG_NF_SOCKET_IPV4)
bcd41303f   KOVACS Krisztian   udp: Export UDP s...
484
485
486
  struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
  			     __be32 daddr, __be16 dport, int dif)
  {
ca065d0cf   Eric Dumazet   udp: no longer us...
487
488
489
  	struct sock *sk;
  
  	sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport,
fb74c2773   David Ahern   net: ipv4: add se...
490
  			       dif, 0, &udp_table, NULL);
41c6d650f   Reshetova, Elena   net: convert sock...
491
  	if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
ca065d0cf   Eric Dumazet   udp: no longer us...
492
493
  		sk = NULL;
  	return sk;
bcd41303f   KOVACS Krisztian   udp: Export UDP s...
494
495
  }
  EXPORT_SYMBOL_GPL(udp4_lib_lookup);
ca065d0cf   Eric Dumazet   udp: no longer us...
496
  #endif
bcd41303f   KOVACS Krisztian   udp: Export UDP s...
497

421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
498
499
500
  static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
  				       __be16 loc_port, __be32 loc_addr,
  				       __be16 rmt_port, __be32 rmt_addr,
fb74c2773   David Ahern   net: ipv4: add se...
501
  				       int dif, int sdif, unsigned short hnum)
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
502
503
504
505
506
507
508
509
510
  {
  	struct inet_sock *inet = inet_sk(sk);
  
  	if (!net_eq(sock_net(sk), net) ||
  	    udp_sk(sk)->udp_port_hash != hnum ||
  	    (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
  	    (inet->inet_dport != rmt_port && inet->inet_dport) ||
  	    (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
  	    ipv6_only_sock(sk) ||
82ba25c6d   Tim Beale   udp: only choose ...
511
  	    !udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
512
  		return false;
60d9b0314   David Ahern   net: ipv4: add se...
513
  	if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif, sdif))
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
514
515
516
  		return false;
  	return true;
  }
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
517
518
519
  DEFINE_STATIC_KEY_FALSE(udp_encap_needed_key);
  void udp_encap_enable(void)
  {
9c4806014   Paolo Abeni   udp: fix jump lab...
520
  	static_branch_inc(&udp_encap_needed_key);
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
521
522
  }
  EXPORT_SYMBOL(udp_encap_enable);
e7cc08245   Stefano Brivio   udp: Support for ...
523
524
525
526
527
528
529
530
531
  /* Handler for tunnels with arbitrary destination ports: no socket lookup, go
   * through error handlers in encapsulations looking for a match.
   */
  static int __udp4_lib_err_encap_no_sk(struct sk_buff *skb, u32 info)
  {
  	int i;
  
  	for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
  		int (*handler)(struct sk_buff *skb, u32 info);
92b953642   Paolo Abeni   udp: fix possible...
532
  		const struct ip_tunnel_encap_ops *encap;
e7cc08245   Stefano Brivio   udp: Support for ...
533

92b953642   Paolo Abeni   udp: fix possible...
534
535
  		encap = rcu_dereference(iptun_encaps[i]);
  		if (!encap)
e7cc08245   Stefano Brivio   udp: Support for ...
536
  			continue;
92b953642   Paolo Abeni   udp: fix possible...
537
  		handler = encap->err_handler;
e7cc08245   Stefano Brivio   udp: Support for ...
538
539
540
541
542
543
  		if (handler && !handler(skb, info))
  			return 0;
  	}
  
  	return -ENOENT;
  }
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
544
545
546
547
548
549
550
  /* Try to match ICMP errors to UDP tunnels by looking up a socket without
   * reversing source and destination port: this will match tunnels that force the
   * same destination port on both endpoints (e.g. VXLAN, GENEVE). Note that
   * lwtunnels might actually break this assumption by being configured with
   * different destination ports on endpoints, in this case we won't be able to
   * trace ICMP messages back to them.
   *
e7cc08245   Stefano Brivio   udp: Support for ...
551
552
553
554
   * If this doesn't match any socket, probe tunnels with arbitrary destination
   * ports (e.g. FoU, GUE): there, the receiving socket is useless, as the port
   * we've sent packets to won't necessarily match the local destination port.
   *
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
555
556
557
   * Then ask the tunnel implementation to match the error against a valid
   * association.
   *
e7cc08245   Stefano Brivio   udp: Support for ...
558
559
   * Return an error if we can't find a match, the socket if we need further
   * processing, zero otherwise.
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
560
561
562
563
564
   */
  static struct sock *__udp4_lib_err_encap(struct net *net,
  					 const struct iphdr *iph,
  					 struct udphdr *uh,
  					 struct udp_table *udptable,
e7cc08245   Stefano Brivio   udp: Support for ...
565
  					 struct sk_buff *skb, u32 info)
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
566
  {
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
567
  	int network_offset, transport_offset;
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
568
  	struct sock *sk;
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
569
570
571
572
573
574
575
576
  	network_offset = skb_network_offset(skb);
  	transport_offset = skb_transport_offset(skb);
  
  	/* Network header needs to point to the outer IPv4 header inside ICMP */
  	skb_reset_network_header(skb);
  
  	/* Transport header needs to point to the UDP header */
  	skb_set_transport_header(skb, iph->ihl << 2);
e7cc08245   Stefano Brivio   udp: Support for ...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  	sk = __udp4_lib_lookup(net, iph->daddr, uh->source,
  			       iph->saddr, uh->dest, skb->dev->ifindex, 0,
  			       udptable, NULL);
  	if (sk) {
  		int (*lookup)(struct sock *sk, struct sk_buff *skb);
  		struct udp_sock *up = udp_sk(sk);
  
  		lookup = READ_ONCE(up->encap_err_lookup);
  		if (!lookup || lookup(sk, skb))
  			sk = NULL;
  	}
  
  	if (!sk)
  		sk = ERR_PTR(__udp4_lib_err_encap_no_sk(skb, info));
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
591
592
593
594
595
596
  
  	skb_set_transport_header(skb, transport_offset);
  	skb_set_network_header(skb, network_offset);
  
  	return sk;
  }
db8dac20d   David S. Miller   [UDP]: Revert udp...
597
598
599
600
601
602
603
604
605
606
  /*
   * This routine is called by the ICMP module when it gets some
   * sort of error condition.  If err < 0 then the socket should
   * be closed and the error returned to the user.  If err > 0
   * it's just the icmp type << 8 | icmp code.
   * Header points to the ip header of the error packet. We move
   * on past this. Then (as it used to claim before adjustment)
   * header points to the first 8 bytes of the udp header.  We need
   * to find the appropriate port.
   */
32bbd8793   Stefano Brivio   net: Convert prot...
607
  int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
db8dac20d   David S. Miller   [UDP]: Revert udp...
608
609
  {
  	struct inet_sock *inet;
b71d1d426   Eric Dumazet   inet: constify ip...
610
  	const struct iphdr *iph = (const struct iphdr *)skb->data;
c482c5685   Eric Dumazet   udp: cleanups
611
  	struct udphdr *uh = (struct udphdr *)(skb->data+(iph->ihl<<2));
db8dac20d   David S. Miller   [UDP]: Revert udp...
612
613
  	const int type = icmp_hdr(skb)->type;
  	const int code = icmp_hdr(skb)->code;
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
614
  	bool tunnel = false;
db8dac20d   David S. Miller   [UDP]: Revert udp...
615
616
617
  	struct sock *sk;
  	int harderr;
  	int err;
fd54d716b   Pavel Emelyanov   inet: toss struct...
618
  	struct net *net = dev_net(skb->dev);
db8dac20d   David S. Miller   [UDP]: Revert udp...
619

fd54d716b   Pavel Emelyanov   inet: toss struct...
620
  	sk = __udp4_lib_lookup(net, iph->daddr, uh->dest,
f64bf6b8a   Mike Manning   net: allow tracer...
621
622
  			       iph->saddr, uh->source, skb->dev->ifindex,
  			       inet_sdif(skb), udptable, NULL);
51456b291   Ian Morris   ipv4: coding styl...
623
  	if (!sk) {
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
624
  		/* No socket for error: try tunnels before discarding */
e7cc08245   Stefano Brivio   udp: Support for ...
625
626
627
628
629
630
631
  		sk = ERR_PTR(-ENOENT);
  		if (static_branch_unlikely(&udp_encap_needed_key)) {
  			sk = __udp4_lib_err_encap(net, iph, uh, udptable, skb,
  						  info);
  			if (!sk)
  				return 0;
  		}
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
632

e7cc08245   Stefano Brivio   udp: Support for ...
633
  		if (IS_ERR(sk)) {
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
634
  			__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
e7cc08245   Stefano Brivio   udp: Support for ...
635
  			return PTR_ERR(sk);
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
636
  		}
e7cc08245   Stefano Brivio   udp: Support for ...
637

a36e185e8   Stefano Brivio   udp: Handle ICMP ...
638
  		tunnel = true;
db8dac20d   David S. Miller   [UDP]: Revert udp...
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  	}
  
  	err = 0;
  	harderr = 0;
  	inet = inet_sk(sk);
  
  	switch (type) {
  	default:
  	case ICMP_TIME_EXCEEDED:
  		err = EHOSTUNREACH;
  		break;
  	case ICMP_SOURCE_QUENCH:
  		goto out;
  	case ICMP_PARAMETERPROB:
  		err = EPROTO;
  		harderr = 1;
  		break;
  	case ICMP_DEST_UNREACH:
  		if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
363933955   David S. Miller   ipv4: Handle PMTU...
658
  			ipv4_sk_update_pmtu(skb, sk, info);
db8dac20d   David S. Miller   [UDP]: Revert udp...
659
660
661
662
663
664
665
666
667
668
669
670
671
  			if (inet->pmtudisc != IP_PMTUDISC_DONT) {
  				err = EMSGSIZE;
  				harderr = 1;
  				break;
  			}
  			goto out;
  		}
  		err = EHOSTUNREACH;
  		if (code <= NR_ICMP_UNREACH) {
  			harderr = icmp_err_convert[code].fatal;
  			err = icmp_err_convert[code].errno;
  		}
  		break;
55be7a9c6   David S. Miller   ipv4: Add redirec...
672
673
  	case ICMP_REDIRECT:
  		ipv4_sk_redirect(skb, sk);
1a462d189   Duan Jiong   net: udp: do not ...
674
  		goto out;
db8dac20d   David S. Miller   [UDP]: Revert udp...
675
676
677
678
679
680
  	}
  
  	/*
  	 *      RFC1122: OK.  Passes ICMP errors back to application, as per
  	 *	4.1.3.3.
  	 */
a36e185e8   Stefano Brivio   udp: Handle ICMP ...
681
682
683
684
  	if (tunnel) {
  		/* ...not for tunnels though: we don't have a sending socket */
  		goto out;
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
685
686
687
  	if (!inet->recverr) {
  		if (!harderr || sk->sk_state != TCP_ESTABLISHED)
  			goto out;
b1faf5666   Eric Dumazet   net: sock_queue_e...
688
  	} else
c482c5685   Eric Dumazet   udp: cleanups
689
  		ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1));
b1faf5666   Eric Dumazet   net: sock_queue_e...
690

db8dac20d   David S. Miller   [UDP]: Revert udp...
691
692
693
  	sk->sk_err = err;
  	sk->sk_error_report(sk);
  out:
32bbd8793   Stefano Brivio   net: Convert prot...
694
  	return 0;
db8dac20d   David S. Miller   [UDP]: Revert udp...
695
  }
32bbd8793   Stefano Brivio   net: Convert prot...
696
  int udp_err(struct sk_buff *skb, u32 info)
db8dac20d   David S. Miller   [UDP]: Revert udp...
697
  {
32bbd8793   Stefano Brivio   net: Convert prot...
698
  	return __udp4_lib_err(skb, info, &udp_table);
db8dac20d   David S. Miller   [UDP]: Revert udp...
699
700
701
702
703
  }
  
  /*
   * Throw away all pending data and cancel the corking. Socket is locked.
   */
36d926b94   Denis V. Lunev   [IPV6]: inet_sk(s...
704
  void udp_flush_pending_frames(struct sock *sk)
db8dac20d   David S. Miller   [UDP]: Revert udp...
705
706
707
708
709
710
711
712
713
  {
  	struct udp_sock *up = udp_sk(sk);
  
  	if (up->pending) {
  		up->len = 0;
  		up->pending = 0;
  		ip_flush_pending_frames(sk);
  	}
  }
36d926b94   Denis V. Lunev   [IPV6]: inet_sk(s...
714
  EXPORT_SYMBOL(udp_flush_pending_frames);
db8dac20d   David S. Miller   [UDP]: Revert udp...
715
716
  
  /**
f6b9664f8   Herbert Xu   udp: Switch to ip...
717
   * 	udp4_hwcsum  -  handle outgoing HW checksumming
db8dac20d   David S. Miller   [UDP]: Revert udp...
718
719
   * 	@skb: 	sk_buff containing the filled-in UDP header
   * 	        (checksum field must be zeroed out)
f6b9664f8   Herbert Xu   udp: Switch to ip...
720
721
   *	@src:	source IP address
   *	@dst:	destination IP address
db8dac20d   David S. Miller   [UDP]: Revert udp...
722
   */
c26bf4a51   Thomas Graf   pktgen: Add UDPCS...
723
  void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
db8dac20d   David S. Miller   [UDP]: Revert udp...
724
  {
db8dac20d   David S. Miller   [UDP]: Revert udp...
725
  	struct udphdr *uh = udp_hdr(skb);
f6b9664f8   Herbert Xu   udp: Switch to ip...
726
727
728
  	int offset = skb_transport_offset(skb);
  	int len = skb->len - offset;
  	int hlen = len;
db8dac20d   David S. Miller   [UDP]: Revert udp...
729
  	__wsum csum = 0;
ebbe495f1   WANG Cong   ipv4: use skb fra...
730
  	if (!skb_has_frag_list(skb)) {
db8dac20d   David S. Miller   [UDP]: Revert udp...
731
732
733
734
735
  		/*
  		 * Only one fragment on the socket.
  		 */
  		skb->csum_start = skb_transport_header(skb) - skb->head;
  		skb->csum_offset = offsetof(struct udphdr, check);
f6b9664f8   Herbert Xu   udp: Switch to ip...
736
737
  		uh->check = ~csum_tcpudp_magic(src, dst, len,
  					       IPPROTO_UDP, 0);
db8dac20d   David S. Miller   [UDP]: Revert udp...
738
  	} else {
ebbe495f1   WANG Cong   ipv4: use skb fra...
739
  		struct sk_buff *frags;
db8dac20d   David S. Miller   [UDP]: Revert udp...
740
741
742
743
744
  		/*
  		 * HW-checksum won't work as there are two or more
  		 * fragments on the socket so that all csums of sk_buffs
  		 * should be together
  		 */
ebbe495f1   WANG Cong   ipv4: use skb fra...
745
  		skb_walk_frags(skb, frags) {
f6b9664f8   Herbert Xu   udp: Switch to ip...
746
747
  			csum = csum_add(csum, frags->csum);
  			hlen -= frags->len;
ebbe495f1   WANG Cong   ipv4: use skb fra...
748
  		}
db8dac20d   David S. Miller   [UDP]: Revert udp...
749

f6b9664f8   Herbert Xu   udp: Switch to ip...
750
  		csum = skb_checksum(skb, offset, hlen, csum);
db8dac20d   David S. Miller   [UDP]: Revert udp...
751
  		skb->ip_summed = CHECKSUM_NONE;
db8dac20d   David S. Miller   [UDP]: Revert udp...
752
753
754
755
756
  		uh->check = csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, csum);
  		if (uh->check == 0)
  			uh->check = CSUM_MANGLED_0;
  	}
  }
c26bf4a51   Thomas Graf   pktgen: Add UDPCS...
757
  EXPORT_SYMBOL_GPL(udp4_hwcsum);
db8dac20d   David S. Miller   [UDP]: Revert udp...
758

af5fcba7f   Tom Herbert   udp: Generic func...
759
760
761
762
763
764
765
  /* Function to set UDP checksum for an IPv4 UDP packet. This is intended
   * for the simple case like when setting the checksum for a UDP tunnel.
   */
  void udp_set_csum(bool nocheck, struct sk_buff *skb,
  		  __be32 saddr, __be32 daddr, int len)
  {
  	struct udphdr *uh = udp_hdr(skb);
179bc67f6   Edward Cree   net: local checks...
766
  	if (nocheck) {
af5fcba7f   Tom Herbert   udp: Generic func...
767
  		uh->check = 0;
179bc67f6   Edward Cree   net: local checks...
768
  	} else if (skb_is_gso(skb)) {
af5fcba7f   Tom Herbert   udp: Generic func...
769
  		uh->check = ~udp_v4_check(len, saddr, daddr, 0);
179bc67f6   Edward Cree   net: local checks...
770
771
772
773
774
  	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
  		uh->check = 0;
  		uh->check = udp_v4_check(len, saddr, daddr, lco_csum(skb));
  		if (uh->check == 0)
  			uh->check = CSUM_MANGLED_0;
d75f1306d   Edward Cree   net: udp: always ...
775
  	} else {
af5fcba7f   Tom Herbert   udp: Generic func...
776
777
778
779
  		skb->ip_summed = CHECKSUM_PARTIAL;
  		skb->csum_start = skb_transport_header(skb) - skb->head;
  		skb->csum_offset = offsetof(struct udphdr, check);
  		uh->check = ~udp_v4_check(len, saddr, daddr, 0);
af5fcba7f   Tom Herbert   udp: Generic func...
780
781
782
  	}
  }
  EXPORT_SYMBOL(udp_set_csum);
bec1f6f69   Willem de Bruijn   udp: generate gso...
783
784
  static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
  			struct inet_cork *cork)
db8dac20d   David S. Miller   [UDP]: Revert udp...
785
  {
f6b9664f8   Herbert Xu   udp: Switch to ip...
786
  	struct sock *sk = skb->sk;
db8dac20d   David S. Miller   [UDP]: Revert udp...
787
  	struct inet_sock *inet = inet_sk(sk);
db8dac20d   David S. Miller   [UDP]: Revert udp...
788
789
790
  	struct udphdr *uh;
  	int err = 0;
  	int is_udplite = IS_UDPLITE(sk);
f6b9664f8   Herbert Xu   udp: Switch to ip...
791
792
  	int offset = skb_transport_offset(skb);
  	int len = skb->len - offset;
4094871db   Josh Hunt   udp: only do GSO ...
793
  	int datalen = len - sizeof(*uh);
db8dac20d   David S. Miller   [UDP]: Revert udp...
794
  	__wsum csum = 0;
db8dac20d   David S. Miller   [UDP]: Revert udp...
795
796
797
798
  	/*
  	 * Create a UDP header
  	 */
  	uh = udp_hdr(skb);
f6b9664f8   Herbert Xu   udp: Switch to ip...
799
  	uh->source = inet->inet_sport;
79ab05314   David S. Miller   ipv4: udp: Elimin...
800
  	uh->dest = fl4->fl4_dport;
f6b9664f8   Herbert Xu   udp: Switch to ip...
801
  	uh->len = htons(len);
db8dac20d   David S. Miller   [UDP]: Revert udp...
802
  	uh->check = 0;
bec1f6f69   Willem de Bruijn   udp: generate gso...
803
804
805
  	if (cork->gso_size) {
  		const int hlen = skb_network_header_len(skb) +
  				 sizeof(struct udphdr);
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
806
807
  		if (hlen + cork->gso_size > cork->fragsize) {
  			kfree_skb(skb);
bec1f6f69   Willem de Bruijn   udp: generate gso...
808
  			return -EINVAL;
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
809
810
811
  		}
  		if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) {
  			kfree_skb(skb);
bec1f6f69   Willem de Bruijn   udp: generate gso...
812
  			return -EINVAL;
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
813
814
815
  		}
  		if (sk->sk_no_check_tx) {
  			kfree_skb(skb);
a8c744a8b   Willem de Bruijn   udp: disable gso ...
816
  			return -EINVAL;
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
817
  		}
ff06342cb   Willem de Bruijn   udp: exclude gso ...
818
  		if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
819
820
  		    dst_xfrm(skb_dst(skb))) {
  			kfree_skb(skb);
bec1f6f69   Willem de Bruijn   udp: generate gso...
821
  			return -EIO;
0f149c9fe   Willem de Bruijn   udp: with udp_seg...
822
  		}
bec1f6f69   Willem de Bruijn   udp: generate gso...
823

4094871db   Josh Hunt   udp: only do GSO ...
824
825
826
827
828
829
  		if (datalen > cork->gso_size) {
  			skb_shinfo(skb)->gso_size = cork->gso_size;
  			skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
  			skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
  								 cork->gso_size);
  		}
a8c744a8b   Willem de Bruijn   udp: disable gso ...
830
  		goto csum_partial;
bec1f6f69   Willem de Bruijn   udp: generate gso...
831
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
832
  	if (is_udplite)  				 /*     UDP-Lite      */
f6b9664f8   Herbert Xu   udp: Switch to ip...
833
  		csum = udplite_csum(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
834

ab2fb7e32   Willem de Bruijn   udp: remove unrea...
835
  	else if (sk->sk_no_check_tx) {			 /* UDP csum off */
db8dac20d   David S. Miller   [UDP]: Revert udp...
836
837
838
839
840
  
  		skb->ip_summed = CHECKSUM_NONE;
  		goto send;
  
  	} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
a8c744a8b   Willem de Bruijn   udp: disable gso ...
841
  csum_partial:
db8dac20d   David S. Miller   [UDP]: Revert udp...
842

79ab05314   David S. Miller   ipv4: udp: Elimin...
843
  		udp4_hwcsum(skb, fl4->saddr, fl4->daddr);
db8dac20d   David S. Miller   [UDP]: Revert udp...
844
  		goto send;
f6b9664f8   Herbert Xu   udp: Switch to ip...
845
846
  	} else
  		csum = udp_csum(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
847
848
  
  	/* add protocol-dependent pseudo-header */
79ab05314   David S. Miller   ipv4: udp: Elimin...
849
  	uh->check = csum_tcpudp_magic(fl4->saddr, fl4->daddr, len,
c482c5685   Eric Dumazet   udp: cleanups
850
  				      sk->sk_protocol, csum);
db8dac20d   David S. Miller   [UDP]: Revert udp...
851
852
853
854
  	if (uh->check == 0)
  		uh->check = CSUM_MANGLED_0;
  
  send:
b5ec8eeac   Eric Dumazet   ipv4: fix ip_send...
855
  	err = ip_send_skb(sock_net(sk), skb);
6ce9e7b5f   Eric Dumazet   ip: Report qdisc ...
856
857
  	if (err) {
  		if (err == -ENOBUFS && !inet->recverr) {
6aef70a85   Eric Dumazet   net: snmp: kill v...
858
859
  			UDP_INC_STATS(sock_net(sk),
  				      UDP_MIB_SNDBUFERRORS, is_udplite);
6ce9e7b5f   Eric Dumazet   ip: Report qdisc ...
860
861
862
  			err = 0;
  		}
  	} else
6aef70a85   Eric Dumazet   net: snmp: kill v...
863
864
  		UDP_INC_STATS(sock_net(sk),
  			      UDP_MIB_OUTDATAGRAMS, is_udplite);
f6b9664f8   Herbert Xu   udp: Switch to ip...
865
866
867
868
869
870
  	return err;
  }
  
  /*
   * Push out all pending data as one UDP datagram. Socket is locked.
   */
8822b64a0   Hannes Frederic Sowa   ipv6: call udp_pu...
871
  int udp_push_pending_frames(struct sock *sk)
f6b9664f8   Herbert Xu   udp: Switch to ip...
872
873
874
  {
  	struct udp_sock  *up = udp_sk(sk);
  	struct inet_sock *inet = inet_sk(sk);
b6f21b268   David S. Miller   ipv4: Use flowi4 ...
875
  	struct flowi4 *fl4 = &inet->cork.fl.u.ip4;
f6b9664f8   Herbert Xu   udp: Switch to ip...
876
877
  	struct sk_buff *skb;
  	int err = 0;
77968b782   David S. Miller   ipv4: Pass flow k...
878
  	skb = ip_finish_skb(sk, fl4);
f6b9664f8   Herbert Xu   udp: Switch to ip...
879
880
  	if (!skb)
  		goto out;
bec1f6f69   Willem de Bruijn   udp: generate gso...
881
  	err = udp_send_skb(skb, fl4, &inet->cork.base);
f6b9664f8   Herbert Xu   udp: Switch to ip...
882

db8dac20d   David S. Miller   [UDP]: Revert udp...
883
884
885
  out:
  	up->len = 0;
  	up->pending = 0;
db8dac20d   David S. Miller   [UDP]: Revert udp...
886
887
  	return err;
  }
8822b64a0   Hannes Frederic Sowa   ipv6: call udp_pu...
888
  EXPORT_SYMBOL(udp_push_pending_frames);
db8dac20d   David S. Miller   [UDP]: Revert udp...
889

2e8de8576   Willem de Bruijn   udp: add gso segm...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
  static int __udp_cmsg_send(struct cmsghdr *cmsg, u16 *gso_size)
  {
  	switch (cmsg->cmsg_type) {
  	case UDP_SEGMENT:
  		if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u16)))
  			return -EINVAL;
  		*gso_size = *(__u16 *)CMSG_DATA(cmsg);
  		return 0;
  	default:
  		return -EINVAL;
  	}
  }
  
  int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size)
  {
  	struct cmsghdr *cmsg;
  	bool need_ip = false;
  	int err;
  
  	for_each_cmsghdr(cmsg, msg) {
  		if (!CMSG_OK(msg, cmsg))
  			return -EINVAL;
  
  		if (cmsg->cmsg_level != SOL_UDP) {
  			need_ip = true;
  			continue;
  		}
  
  		err = __udp_cmsg_send(cmsg, gso_size);
  		if (err)
  			return err;
  	}
  
  	return need_ip;
  }
  EXPORT_SYMBOL_GPL(udp_cmsg_send);
1b7841404   Ying Xue   net: Remove iocb ...
926
  int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
db8dac20d   David S. Miller   [UDP]: Revert udp...
927
928
929
  {
  	struct inet_sock *inet = inet_sk(sk);
  	struct udp_sock *up = udp_sk(sk);
1cedee13d   Andrey Ignatov   bpf: Hooks for sy...
930
  	DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
e474995f2   David S. Miller   udp: Use flow key...
931
  	struct flowi4 fl4_stack;
b6f21b268   David S. Miller   ipv4: Use flowi4 ...
932
  	struct flowi4 *fl4;
db8dac20d   David S. Miller   [UDP]: Revert udp...
933
934
935
936
937
938
939
940
941
942
943
  	int ulen = len;
  	struct ipcm_cookie ipc;
  	struct rtable *rt = NULL;
  	int free = 0;
  	int connected = 0;
  	__be32 daddr, faddr, saddr;
  	__be16 dport;
  	u8  tos;
  	int err, is_udplite = IS_UDPLITE(sk);
  	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
  	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
903ab86d1   Herbert Xu   udp: Add lockless...
944
  	struct sk_buff *skb;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
945
  	struct ip_options_data opt_copy;
db8dac20d   David S. Miller   [UDP]: Revert udp...
946
947
948
949
950
951
952
  
  	if (len > 0xFFFF)
  		return -EMSGSIZE;
  
  	/*
  	 *	Check the flags.
  	 */
c482c5685   Eric Dumazet   udp: cleanups
953
  	if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
db8dac20d   David S. Miller   [UDP]: Revert udp...
954
  		return -EOPNOTSUPP;
903ab86d1   Herbert Xu   udp: Add lockless...
955
  	getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
f5fca6086   David S. Miller   ipv4: Pass flow k...
956
  	fl4 = &inet->cork.fl.u.ip4;
db8dac20d   David S. Miller   [UDP]: Revert udp...
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
  	if (up->pending) {
  		/*
  		 * There are pending frames.
  		 * The socket lock must be held while it's corked.
  		 */
  		lock_sock(sk);
  		if (likely(up->pending)) {
  			if (unlikely(up->pending != AF_INET)) {
  				release_sock(sk);
  				return -EINVAL;
  			}
  			goto do_append_data;
  		}
  		release_sock(sk);
  	}
  	ulen += sizeof(struct udphdr);
  
  	/*
  	 *	Get and verify the address.
  	 */
1cedee13d   Andrey Ignatov   bpf: Hooks for sy...
977
  	if (usin) {
db8dac20d   David S. Miller   [UDP]: Revert udp...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
  		if (msg->msg_namelen < sizeof(*usin))
  			return -EINVAL;
  		if (usin->sin_family != AF_INET) {
  			if (usin->sin_family != AF_UNSPEC)
  				return -EAFNOSUPPORT;
  		}
  
  		daddr = usin->sin_addr.s_addr;
  		dport = usin->sin_port;
  		if (dport == 0)
  			return -EINVAL;
  	} else {
  		if (sk->sk_state != TCP_ESTABLISHED)
  			return -EDESTADDRREQ;
c720c7e83   Eric Dumazet   inet: rename some...
992
993
  		daddr = inet->inet_daddr;
  		dport = inet->inet_dport;
db8dac20d   David S. Miller   [UDP]: Revert udp...
994
995
996
997
998
  		/* Open fast path for connected socket.
  		   Route will not be used, if at least one option is set.
  		 */
  		connected = 1;
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
999

351782067   Willem de Bruijn   ipv4: ipcm_cookie...
1000
  	ipcm_init_sk(&ipc, inet);
bec1f6f69   Willem de Bruijn   udp: generate gso...
1001
  	ipc.gso_size = up->gso_size;
bf84a0106   Daniel Borkmann   net: sock: make s...
1002

db8dac20d   David S. Miller   [UDP]: Revert udp...
1003
  	if (msg->msg_controllen) {
2e8de8576   Willem de Bruijn   udp: add gso segm...
1004
1005
1006
1007
1008
  		err = udp_cmsg_send(sk, msg, &ipc.gso_size);
  		if (err > 0)
  			err = ip_cmsg_send(sk, msg, &ipc,
  					   sk->sk_family == AF_INET6);
  		if (unlikely(err < 0)) {
919483096   Eric Dumazet   ipv4: fix memory ...
1009
  			kfree(ipc.opt);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1010
  			return err;
919483096   Eric Dumazet   ipv4: fix memory ...
1011
  		}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1012
1013
1014
1015
  		if (ipc.opt)
  			free = 1;
  		connected = 0;
  	}
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
  	if (!ipc.opt) {
  		struct ip_options_rcu *inet_opt;
  
  		rcu_read_lock();
  		inet_opt = rcu_dereference(inet->inet_opt);
  		if (inet_opt) {
  			memcpy(&opt_copy, inet_opt,
  			       sizeof(*inet_opt) + inet_opt->opt.optlen);
  			ipc.opt = &opt_copy.opt;
  		}
  		rcu_read_unlock();
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1028

1cedee13d   Andrey Ignatov   bpf: Hooks for sy...
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
  	if (cgroup_bpf_enabled && !connected) {
  		err = BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk,
  					    (struct sockaddr *)usin, &ipc.addr);
  		if (err)
  			goto out_free;
  		if (usin) {
  			if (usin->sin_port == 0) {
  				/* BPF program set invalid port. Reject it. */
  				err = -EINVAL;
  				goto out_free;
  			}
  			daddr = usin->sin_addr.s_addr;
  			dport = usin->sin_port;
  		}
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1044
1045
  	saddr = ipc.addr;
  	ipc.addr = faddr = daddr;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1046
  	if (ipc.opt && ipc.opt->opt.srr) {
1b97013bf   Andrey Ignatov   ipv4: fix memory ...
1047
1048
1049
1050
  		if (!daddr) {
  			err = -EINVAL;
  			goto out_free;
  		}
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1051
  		faddr = ipc.opt->opt.faddr;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1052
1053
  		connected = 0;
  	}
aa6615814   Francesco Fusco   ipv4: processing ...
1054
  	tos = get_rttos(&ipc, inet);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1055
1056
  	if (sock_flag(sk, SOCK_LOCALROUTE) ||
  	    (msg->msg_flags & MSG_DONTROUTE) ||
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1057
  	    (ipc.opt && ipc.opt->opt.is_strictroute)) {
db8dac20d   David S. Miller   [UDP]: Revert udp...
1058
1059
1060
1061
1062
  		tos |= RTO_ONLINK;
  		connected = 0;
  	}
  
  	if (ipv4_is_multicast(daddr)) {
854da9917   Robert Shearman   ipv4: Allow sendi...
1063
  		if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
db8dac20d   David S. Miller   [UDP]: Revert udp...
1064
1065
1066
1067
  			ipc.oif = inet->mc_index;
  		if (!saddr)
  			saddr = inet->mc_addr;
  		connected = 0;
9515a2e08   David Ahern   net/ipv4: Allow s...
1068
  	} else if (!ipc.oif) {
76e21053b   Erich E. Hoover   ipv4: Implement I...
1069
  		ipc.oif = inet->uc_index;
9515a2e08   David Ahern   net/ipv4: Allow s...
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
  	} else if (ipv4_is_lbcast(daddr) && inet->uc_index) {
  		/* oif is set, packet is to local broadcast and
  		 * and uc_index is set. oif is most likely set
  		 * by sk_bound_dev_if. If uc_index != oif check if the
  		 * oif is an L3 master and uc_index is an L3 slave.
  		 * If so, we want to allow the send using the uc_index.
  		 */
  		if (ipc.oif != inet->uc_index &&
  		    ipc.oif == l3mdev_master_ifindex_by_index(sock_net(sk),
  							      inet->uc_index)) {
  			ipc.oif = inet->uc_index;
  		}
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1083
1084
  
  	if (connected)
c482c5685   Eric Dumazet   udp: cleanups
1085
  		rt = (struct rtable *)sk_dst_check(sk, 0);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1086

51456b291   Ian Morris   ipv4: coding styl...
1087
  	if (!rt) {
84a3aa000   Pavel Emelyanov   ipv4: prepare net...
1088
  		struct net *net = sock_net(sk);
9a24abfa4   David Ahern   udp: Handle VRF d...
1089
  		__u8 flow_flags = inet_sk_flowi_flags(sk);
84a3aa000   Pavel Emelyanov   ipv4: prepare net...
1090

e474995f2   David S. Miller   udp: Use flow key...
1091
  		fl4 = &fl4_stack;
9a24abfa4   David Ahern   udp: Handle VRF d...
1092

c6af0c227   Willem de Bruijn   ip: support SO_MA...
1093
  		flowi4_init_output(fl4, ipc.oif, ipc.sockc.mark, tos,
c0951cbcf   David S. Miller   ipv4: Use flowi4_...
1094
  				   RT_SCOPE_UNIVERSE, sk->sk_protocol,
9a24abfa4   David Ahern   udp: Handle VRF d...
1095
  				   flow_flags,
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
1096
1097
  				   faddr, saddr, dport, inet->inet_sport,
  				   sk->sk_uid);
c0951cbcf   David S. Miller   ipv4: Use flowi4_...
1098

e474995f2   David S. Miller   udp: Use flow key...
1099
1100
  		security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
  		rt = ip_route_output_flow(net, fl4, sk);
b23dd4fe4   David S. Miller   ipv4: Make output...
1101
1102
  		if (IS_ERR(rt)) {
  			err = PTR_ERR(rt);
06dc94b1e   David S. Miller   ipv4: Fix crash i...
1103
  			rt = NULL;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1104
  			if (err == -ENETUNREACH)
f1d8cba61   Eric Dumazet   inet: fix possibl...
1105
  				IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1106
1107
1108
1109
1110
1111
1112
1113
  			goto out;
  		}
  
  		err = -EACCES;
  		if ((rt->rt_flags & RTCF_BROADCAST) &&
  		    !sock_flag(sk, SOCK_BROADCAST))
  			goto out;
  		if (connected)
d8d1f30b9   Changli Gao   net-next: remove ...
1114
  			sk_dst_set(sk, dst_clone(&rt->dst));
db8dac20d   David S. Miller   [UDP]: Revert udp...
1115
1116
1117
1118
1119
  	}
  
  	if (msg->msg_flags&MSG_CONFIRM)
  		goto do_confirm;
  back_from_confirm:
e474995f2   David S. Miller   udp: Use flow key...
1120
  	saddr = fl4->saddr;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1121
  	if (!ipc.addr)
e474995f2   David S. Miller   udp: Use flow key...
1122
  		daddr = ipc.addr = fl4->daddr;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1123

903ab86d1   Herbert Xu   udp: Add lockless...
1124
1125
  	/* Lockless fast path for the non-corking case. */
  	if (!corkreq) {
1cd7884df   Willem de Bruijn   udp: expose inet ...
1126
  		struct inet_cork cork;
f69e6d131   Al Viro   ip_generic_getfra...
1127
  		skb = ip_make_skb(sk, fl4, getfrag, msg, ulen,
903ab86d1   Herbert Xu   udp: Add lockless...
1128
  				  sizeof(struct udphdr), &ipc, &rt,
1cd7884df   Willem de Bruijn   udp: expose inet ...
1129
  				  &cork, msg->msg_flags);
903ab86d1   Herbert Xu   udp: Add lockless...
1130
  		err = PTR_ERR(skb);
50c3a487d   YOSHIFUJI Hideaki / 吉藤英明   ipv4: Use IS_ERR_...
1131
  		if (!IS_ERR_OR_NULL(skb))
bec1f6f69   Willem de Bruijn   udp: generate gso...
1132
  			err = udp_send_skb(skb, fl4, &cork);
903ab86d1   Herbert Xu   udp: Add lockless...
1133
1134
  		goto out;
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1135
1136
1137
1138
1139
  	lock_sock(sk);
  	if (unlikely(up->pending)) {
  		/* The socket is already corked while preparing it. */
  		/* ... which is an evident application bug. --ANK */
  		release_sock(sk);
197df02cb   Matteo Croce   udp: make some me...
1140
1141
  		net_dbg_ratelimited("socket already corked
  ");
db8dac20d   David S. Miller   [UDP]: Revert udp...
1142
1143
1144
1145
1146
1147
  		err = -EINVAL;
  		goto out;
  	}
  	/*
  	 *	Now cork the socket to pend data.
  	 */
b6f21b268   David S. Miller   ipv4: Use flowi4 ...
1148
1149
1150
  	fl4 = &inet->cork.fl.u.ip4;
  	fl4->daddr = daddr;
  	fl4->saddr = saddr;
9cce96df5   David S. Miller   net: Put fl4_* ma...
1151
1152
  	fl4->fl4_dport = dport;
  	fl4->fl4_sport = inet->inet_sport;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1153
1154
1155
1156
  	up->pending = AF_INET;
  
  do_append_data:
  	up->len += ulen;
f69e6d131   Al Viro   ip_generic_getfra...
1157
  	err = ip_append_data(sk, fl4, getfrag, msg, ulen,
f5fca6086   David S. Miller   ipv4: Pass flow k...
1158
1159
  			     sizeof(struct udphdr), &ipc, &rt,
  			     corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  	if (err)
  		udp_flush_pending_frames(sk);
  	else if (!corkreq)
  		err = udp_push_pending_frames(sk);
  	else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
  		up->pending = 0;
  	release_sock(sk);
  
  out:
  	ip_rt_put(rt);
1b97013bf   Andrey Ignatov   ipv4: fix memory ...
1170
  out_free:
db8dac20d   David S. Miller   [UDP]: Revert udp...
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
  	if (free)
  		kfree(ipc.opt);
  	if (!err)
  		return len;
  	/*
  	 * ENOBUFS = no kernel mem, SOCK_NOSPACE = no sndbuf space.  Reporting
  	 * ENOBUFS might not be good (it's not tunable per se), but otherwise
  	 * we don't have a good statistic (IpOutDiscards but it can be too many
  	 * things).  We could add another new stat but at least for now that
  	 * seems like overkill.
  	 */
  	if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
6aef70a85   Eric Dumazet   net: snmp: kill v...
1183
1184
  		UDP_INC_STATS(sock_net(sk),
  			      UDP_MIB_SNDBUFERRORS, is_udplite);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1185
1186
1187
1188
  	}
  	return err;
  
  do_confirm:
0dec879f6   Julian Anastasov   net: use dst_conf...
1189
1190
  	if (msg->msg_flags & MSG_PROBE)
  		dst_confirm_neigh(&rt->dst, &fl4->daddr);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1191
1192
1193
1194
1195
  	if (!(msg->msg_flags&MSG_PROBE) || len)
  		goto back_from_confirm;
  	err = 0;
  	goto out;
  }
c482c5685   Eric Dumazet   udp: cleanups
1196
  EXPORT_SYMBOL(udp_sendmsg);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1197
1198
1199
1200
  
  int udp_sendpage(struct sock *sk, struct page *page, int offset,
  		 size_t size, int flags)
  {
f5fca6086   David S. Miller   ipv4: Pass flow k...
1201
  	struct inet_sock *inet = inet_sk(sk);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1202
1203
  	struct udp_sock *up = udp_sk(sk);
  	int ret;
d3f7d56a7   Shawn Landden   net: update consu...
1204
1205
  	if (flags & MSG_SENDPAGE_NOTLAST)
  		flags |= MSG_MORE;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1206
1207
1208
1209
1210
1211
1212
  	if (!up->pending) {
  		struct msghdr msg = {	.msg_flags = flags|MSG_MORE };
  
  		/* Call udp_sendmsg to specify destination address which
  		 * sendpage interface can't pass.
  		 * This will succeed only when the socket is connected.
  		 */
1b7841404   Ying Xue   net: Remove iocb ...
1213
  		ret = udp_sendmsg(sk, &msg, 0);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1214
1215
1216
1217
1218
1219
1220
1221
  		if (ret < 0)
  			return ret;
  	}
  
  	lock_sock(sk);
  
  	if (unlikely(!up->pending)) {
  		release_sock(sk);
197df02cb   Matteo Croce   udp: make some me...
1222
1223
  		net_dbg_ratelimited("cork failed
  ");
db8dac20d   David S. Miller   [UDP]: Revert udp...
1224
1225
  		return -EINVAL;
  	}
f5fca6086   David S. Miller   ipv4: Pass flow k...
1226
1227
  	ret = ip_append_page(sk, &inet->cork.fl.u.ip4,
  			     page, offset, size, flags);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
  	if (ret == -EOPNOTSUPP) {
  		release_sock(sk);
  		return sock_no_sendpage(sk->sk_socket, page, offset,
  					size, flags);
  	}
  	if (ret < 0) {
  		udp_flush_pending_frames(sk);
  		goto out;
  	}
  
  	up->len += size;
  	if (!(up->corkflag || (flags&MSG_MORE)))
  		ret = udp_push_pending_frames(sk);
  	if (!ret)
  		ret = size;
  out:
  	release_sock(sk);
  	return ret;
  }
dce4551cb   Paolo Abeni   udp: preserve hea...
1247
  #define UDP_SKB_IS_STATELESS 0x80000000
677bf08cf   Florian Westphal   udp: drop skb ext...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
  /* all head states (dst, sk, nf conntrack) except skb extensions are
   * cleared by udp_rcv().
   *
   * We need to preserve secpath, if present, to eventually process
   * IP_CMSG_PASSSEC at recvmsg() time.
   *
   * Other extensions can be cleared.
   */
  static bool udp_try_make_stateless(struct sk_buff *skb)
  {
  	if (!skb_has_extensions(skb))
  		return true;
  
  	if (!secpath_exists(skb)) {
  		skb_ext_reset(skb);
  		return true;
  	}
  
  	return false;
  }
b65ac4467   Paolo Abeni   udp: try to avoid...
1268
1269
  static void udp_set_dev_scratch(struct sk_buff *skb)
  {
dce4551cb   Paolo Abeni   udp: preserve hea...
1270
  	struct udp_dev_scratch *scratch = udp_skb_scratch(skb);
b65ac4467   Paolo Abeni   udp: try to avoid...
1271
1272
  
  	BUILD_BUG_ON(sizeof(struct udp_dev_scratch) > sizeof(long));
dce4551cb   Paolo Abeni   udp: preserve hea...
1273
1274
  	scratch->_tsize_state = skb->truesize;
  #if BITS_PER_LONG == 64
b65ac4467   Paolo Abeni   udp: try to avoid...
1275
1276
1277
  	scratch->len = skb->len;
  	scratch->csum_unnecessary = !!skb_csum_unnecessary(skb);
  	scratch->is_linear = !skb_is_nonlinear(skb);
dce4551cb   Paolo Abeni   udp: preserve hea...
1278
  #endif
677bf08cf   Florian Westphal   udp: drop skb ext...
1279
  	if (udp_try_make_stateless(skb))
dce4551cb   Paolo Abeni   udp: preserve hea...
1280
  		scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
b65ac4467   Paolo Abeni   udp: try to avoid...
1281
  }
a793183ca   Eric Dumazet   udp: fix data-rac...
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
  static void udp_skb_csum_unnecessary_set(struct sk_buff *skb)
  {
  	/* We come here after udp_lib_checksum_complete() returned 0.
  	 * This means that __skb_checksum_complete() might have
  	 * set skb->csum_valid to 1.
  	 * On 64bit platforms, we can set csum_unnecessary
  	 * to true, but only if the skb is not shared.
  	 */
  #if BITS_PER_LONG == 64
  	if (!skb_shared(skb))
  		udp_skb_scratch(skb)->csum_unnecessary = true;
  #endif
  }
b65ac4467   Paolo Abeni   udp: try to avoid...
1295
1296
  static int udp_skb_truesize(struct sk_buff *skb)
  {
dce4551cb   Paolo Abeni   udp: preserve hea...
1297
  	return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS;
b65ac4467   Paolo Abeni   udp: try to avoid...
1298
  }
dce4551cb   Paolo Abeni   udp: preserve hea...
1299
  static bool udp_skb_has_head_state(struct sk_buff *skb)
b65ac4467   Paolo Abeni   udp: try to avoid...
1300
  {
dce4551cb   Paolo Abeni   udp: preserve hea...
1301
  	return !(udp_skb_scratch(skb)->_tsize_state & UDP_SKB_IS_STATELESS);
b65ac4467   Paolo Abeni   udp: try to avoid...
1302
  }
b65ac4467   Paolo Abeni   udp: try to avoid...
1303

7c13f97ff   Paolo Abeni   udp: do fwd memor...
1304
  /* fully reclaim rmem/fwd memory allocated for skb */
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1305
1306
  static void udp_rmem_release(struct sock *sk, int size, int partial,
  			     bool rx_queue_lock_held)
f970bd9e3   Paolo Abeni   udp: implement me...
1307
  {
6b229cf77   Eric Dumazet   udp: add batching...
1308
  	struct udp_sock *up = udp_sk(sk);
2276f58ac   Paolo Abeni   udp: use a separa...
1309
  	struct sk_buff_head *sk_queue;
f970bd9e3   Paolo Abeni   udp: implement me...
1310
  	int amt;
6b229cf77   Eric Dumazet   udp: add batching...
1311
1312
1313
  	if (likely(partial)) {
  		up->forward_deficit += size;
  		size = up->forward_deficit;
41c230ae2   Paolo Abeni   Revert "udp: do r...
1314
1315
  		if (size < (sk->sk_rcvbuf >> 2) &&
  		    !skb_queue_empty(&up->reader_queue))
6b229cf77   Eric Dumazet   udp: add batching...
1316
1317
1318
1319
1320
  			return;
  	} else {
  		size += up->forward_deficit;
  	}
  	up->forward_deficit = 0;
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1321
1322
1323
  	/* acquire the sk_receive_queue for fwd allocated memory scheduling,
  	 * if the called don't held it already
  	 */
2276f58ac   Paolo Abeni   udp: use a separa...
1324
  	sk_queue = &sk->sk_receive_queue;
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1325
1326
  	if (!rx_queue_lock_held)
  		spin_lock(&sk_queue->lock);
2276f58ac   Paolo Abeni   udp: use a separa...
1327

f970bd9e3   Paolo Abeni   udp: implement me...
1328
1329
1330
  	sk->sk_forward_alloc += size;
  	amt = (sk->sk_forward_alloc - partial) & ~(SK_MEM_QUANTUM - 1);
  	sk->sk_forward_alloc -= amt;
f970bd9e3   Paolo Abeni   udp: implement me...
1331
1332
1333
  
  	if (amt)
  		__sk_mem_reduce_allocated(sk, amt >> SK_MEM_QUANTUM_SHIFT);
02ab0d139   Eric Dumazet   udp: udp_rmem_rel...
1334
1335
  
  	atomic_sub(size, &sk->sk_rmem_alloc);
2276f58ac   Paolo Abeni   udp: use a separa...
1336
1337
1338
  
  	/* this can save us from acquiring the rx queue lock on next receive */
  	skb_queue_splice_tail_init(sk_queue, &up->reader_queue);
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1339
1340
  	if (!rx_queue_lock_held)
  		spin_unlock(&sk_queue->lock);
f970bd9e3   Paolo Abeni   udp: implement me...
1341
  }
2276f58ac   Paolo Abeni   udp: use a separa...
1342
  /* Note: called with reader_queue.lock held.
c84d94905   Eric Dumazet   udp: copy skb->tr...
1343
1344
1345
1346
   * Instead of using skb->truesize here, find a copy of it in skb->dev_scratch
   * This avoids a cache line miss while receive_queue lock is held.
   * Look at __udp_enqueue_schedule_skb() to find where this copy is done.
   */
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1347
  void udp_skb_destructor(struct sock *sk, struct sk_buff *skb)
f970bd9e3   Paolo Abeni   udp: implement me...
1348
  {
b65ac4467   Paolo Abeni   udp: try to avoid...
1349
1350
  	prefetch(&skb->data);
  	udp_rmem_release(sk, udp_skb_truesize(skb), 1, false);
f970bd9e3   Paolo Abeni   udp: implement me...
1351
  }
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1352
  EXPORT_SYMBOL(udp_skb_destructor);
f970bd9e3   Paolo Abeni   udp: implement me...
1353

6dfb4367c   Paolo Abeni   udp: keep the sk_...
1354
  /* as above, but the caller held the rx queue lock, too */
64f5102dc   Colin Ian King   udp: make functio...
1355
  static void udp_skb_dtor_locked(struct sock *sk, struct sk_buff *skb)
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1356
  {
b65ac4467   Paolo Abeni   udp: try to avoid...
1357
1358
  	prefetch(&skb->data);
  	udp_rmem_release(sk, udp_skb_truesize(skb), 1, true);
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1359
  }
4b272750d   Eric Dumazet   udp: add busylock...
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
  /* Idea of busylocks is to let producers grab an extra spinlock
   * to relieve pressure on the receive_queue spinlock shared by consumer.
   * Under flood, this means that only one producer can be in line
   * trying to acquire the receive_queue spinlock.
   * These busylock can be allocated on a per cpu manner, instead of a
   * per socket one (that would consume a cache line per socket)
   */
  static int udp_busylocks_log __read_mostly;
  static spinlock_t *udp_busylocks __read_mostly;
  
  static spinlock_t *busylock_acquire(void *ptr)
  {
  	spinlock_t *busy;
  
  	busy = udp_busylocks + hash_ptr(ptr, udp_busylocks_log);
  	spin_lock(busy);
  	return busy;
  }
  
  static void busylock_release(spinlock_t *busy)
  {
  	if (busy)
  		spin_unlock(busy);
  }
f970bd9e3   Paolo Abeni   udp: implement me...
1384
1385
1386
1387
  int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
  {
  	struct sk_buff_head *list = &sk->sk_receive_queue;
  	int rmem, delta, amt, err = -ENOMEM;
4b272750d   Eric Dumazet   udp: add busylock...
1388
  	spinlock_t *busy = NULL;
c8c8b1270   Eric Dumazet   udp: under rx pre...
1389
  	int size;
f970bd9e3   Paolo Abeni   udp: implement me...
1390
1391
1392
1393
1394
  
  	/* try to avoid the costly atomic add/sub pair when the receive
  	 * queue is full; always allow at least a packet
  	 */
  	rmem = atomic_read(&sk->sk_rmem_alloc);
363dc73ac   Paolo Abeni   udp: be less cons...
1395
  	if (rmem > sk->sk_rcvbuf)
f970bd9e3   Paolo Abeni   udp: implement me...
1396
  		goto drop;
c8c8b1270   Eric Dumazet   udp: under rx pre...
1397
1398
1399
1400
1401
1402
  	/* Under mem pressure, it might be helpful to help udp_recvmsg()
  	 * having linear skbs :
  	 * - Reduce memory overhead and thus increase receive queue capacity
  	 * - Less cache line misses at copyout() time
  	 * - Less work at consume_skb() (less alien page frag freeing)
  	 */
4b272750d   Eric Dumazet   udp: add busylock...
1403
  	if (rmem > (sk->sk_rcvbuf >> 1)) {
c8c8b1270   Eric Dumazet   udp: under rx pre...
1404
  		skb_condense(skb);
4b272750d   Eric Dumazet   udp: add busylock...
1405
1406
1407
  
  		busy = busylock_acquire(sk);
  	}
c8c8b1270   Eric Dumazet   udp: under rx pre...
1408
  	size = skb->truesize;
b65ac4467   Paolo Abeni   udp: try to avoid...
1409
  	udp_set_dev_scratch(skb);
c8c8b1270   Eric Dumazet   udp: under rx pre...
1410

f970bd9e3   Paolo Abeni   udp: implement me...
1411
1412
1413
1414
  	/* we drop only if the receive buf is full and the receive
  	 * queue contains some other skb
  	 */
  	rmem = atomic_add_return(size, &sk->sk_rmem_alloc);
ff4839120   Antonio Messina   udp: fix integer ...
1415
  	if (rmem > (size + (unsigned int)sk->sk_rcvbuf))
f970bd9e3   Paolo Abeni   udp: implement me...
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
  		goto uncharge_drop;
  
  	spin_lock(&list->lock);
  	if (size >= sk->sk_forward_alloc) {
  		amt = sk_mem_pages(size);
  		delta = amt << SK_MEM_QUANTUM_SHIFT;
  		if (!__sk_mem_raise_allocated(sk, delta, amt, SK_MEM_RECV)) {
  			err = -ENOBUFS;
  			spin_unlock(&list->lock);
  			goto uncharge_drop;
  		}
  
  		sk->sk_forward_alloc += delta;
  	}
  
  	sk->sk_forward_alloc -= size;
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1432
1433
1434
  	/* no need to setup a destructor, we will explicitly release the
  	 * forward allocated memory on dequeue
  	 */
f970bd9e3   Paolo Abeni   udp: implement me...
1435
1436
1437
1438
1439
1440
1441
  	sock_skb_set_dropcount(sk, skb);
  
  	__skb_queue_tail(list, skb);
  	spin_unlock(&list->lock);
  
  	if (!sock_flag(sk, SOCK_DEAD))
  		sk->sk_data_ready(sk);
4b272750d   Eric Dumazet   udp: add busylock...
1442
  	busylock_release(busy);
f970bd9e3   Paolo Abeni   udp: implement me...
1443
1444
1445
1446
1447
1448
1449
  	return 0;
  
  uncharge_drop:
  	atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
  
  drop:
  	atomic_inc(&sk->sk_drops);
4b272750d   Eric Dumazet   udp: add busylock...
1450
  	busylock_release(busy);
f970bd9e3   Paolo Abeni   udp: implement me...
1451
1452
1453
  	return err;
  }
  EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
c915fe13c   Paolo Abeni   udplite: fix NULL...
1454
  void udp_destruct_sock(struct sock *sk)
f970bd9e3   Paolo Abeni   udp: implement me...
1455
1456
  {
  	/* reclaim completely the forward allocated memory */
2276f58ac   Paolo Abeni   udp: use a separa...
1457
  	struct udp_sock *up = udp_sk(sk);
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1458
1459
  	unsigned int total = 0;
  	struct sk_buff *skb;
2276f58ac   Paolo Abeni   udp: use a separa...
1460
1461
  	skb_queue_splice_tail_init(&sk->sk_receive_queue, &up->reader_queue);
  	while ((skb = __skb_dequeue(&up->reader_queue)) != NULL) {
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1462
1463
1464
  		total += skb->truesize;
  		kfree_skb(skb);
  	}
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1465
  	udp_rmem_release(sk, total, 0, true);
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1466

f970bd9e3   Paolo Abeni   udp: implement me...
1467
1468
  	inet_sock_destruct(sk);
  }
c915fe13c   Paolo Abeni   udplite: fix NULL...
1469
  EXPORT_SYMBOL_GPL(udp_destruct_sock);
f970bd9e3   Paolo Abeni   udp: implement me...
1470
1471
1472
  
  int udp_init_sock(struct sock *sk)
  {
2276f58ac   Paolo Abeni   udp: use a separa...
1473
  	skb_queue_head_init(&udp_sk(sk)->reader_queue);
f970bd9e3   Paolo Abeni   udp: implement me...
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
  	sk->sk_destruct = udp_destruct_sock;
  	return 0;
  }
  EXPORT_SYMBOL_GPL(udp_init_sock);
  
  void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
  {
  	if (unlikely(READ_ONCE(sk->sk_peek_off) >= 0)) {
  		bool slow = lock_sock_fast(sk);
  
  		sk_peek_offset_bwd(sk, len);
  		unlock_sock_fast(sk, slow);
  	}
0a463c78d   Paolo Abeni   udp: avoid a cach...
1487

ca2c1418e   Paolo Abeni   udp: drop head st...
1488
1489
  	if (!skb_unref(skb))
  		return;
dce4551cb   Paolo Abeni   udp: preserve hea...
1490
1491
  	/* In the more common cases we cleared the head states previously,
  	 * see __udp_queue_rcv_skb().
0ddf3fb2c   Paolo Abeni   udp: preserve skb...
1492
  	 */
dce4551cb   Paolo Abeni   udp: preserve hea...
1493
  	if (unlikely(udp_skb_has_head_state(skb)))
0ddf3fb2c   Paolo Abeni   udp: preserve skb...
1494
  		skb_release_head_state(skb);
ca2c1418e   Paolo Abeni   udp: drop head st...
1495
  	__consume_stateless_skb(skb);
f970bd9e3   Paolo Abeni   udp: implement me...
1496
1497
  }
  EXPORT_SYMBOL_GPL(skb_consume_udp);
2276f58ac   Paolo Abeni   udp: use a separa...
1498
1499
1500
1501
1502
  static struct sk_buff *__first_packet_length(struct sock *sk,
  					     struct sk_buff_head *rcvq,
  					     int *total)
  {
  	struct sk_buff *skb;
9bd780f5e   Paolo Abeni   udp: fix poll()
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
  	while ((skb = skb_peek(rcvq)) != NULL) {
  		if (udp_lib_checksum_complete(skb)) {
  			__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS,
  					IS_UDPLITE(sk));
  			__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
  					IS_UDPLITE(sk));
  			atomic_inc(&sk->sk_drops);
  			__skb_unlink(skb, rcvq);
  			*total += skb->truesize;
  			kfree_skb(skb);
  		} else {
a793183ca   Eric Dumazet   udp: fix data-rac...
1514
  			udp_skb_csum_unnecessary_set(skb);
9bd780f5e   Paolo Abeni   udp: fix poll()
1515
1516
  			break;
  		}
2276f58ac   Paolo Abeni   udp: use a separa...
1517
1518
1519
  	}
  	return skb;
  }
855846720   Eric Dumazet   udp: Fix udp_poll...
1520
1521
1522
1523
1524
  /**
   *	first_packet_length	- return length of first packet in receive queue
   *	@sk: socket
   *
   *	Drops all bad checksum frames, until a valid one is found.
e83c6744e   Eric Dumazet   udp: fix poll() i...
1525
   *	Returns the length of found skb, or -1 if none is found.
855846720   Eric Dumazet   udp: Fix udp_poll...
1526
   */
e83c6744e   Eric Dumazet   udp: fix poll() i...
1527
  static int first_packet_length(struct sock *sk)
855846720   Eric Dumazet   udp: Fix udp_poll...
1528
  {
2276f58ac   Paolo Abeni   udp: use a separa...
1529
1530
  	struct sk_buff_head *rcvq = &udp_sk(sk)->reader_queue;
  	struct sk_buff_head *sk_queue = &sk->sk_receive_queue;
855846720   Eric Dumazet   udp: Fix udp_poll...
1531
  	struct sk_buff *skb;
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1532
  	int total = 0;
e83c6744e   Eric Dumazet   udp: fix poll() i...
1533
  	int res;
855846720   Eric Dumazet   udp: Fix udp_poll...
1534

855846720   Eric Dumazet   udp: Fix udp_poll...
1535
  	spin_lock_bh(&rcvq->lock);
2276f58ac   Paolo Abeni   udp: use a separa...
1536
  	skb = __first_packet_length(sk, rcvq, &total);
137a0dbe3   Eric Dumazet   udp: use skb_queu...
1537
  	if (!skb && !skb_queue_empty_lockless(sk_queue)) {
2276f58ac   Paolo Abeni   udp: use a separa...
1538
1539
1540
1541
1542
  		spin_lock(&sk_queue->lock);
  		skb_queue_splice_tail_init(sk_queue, rcvq);
  		spin_unlock(&sk_queue->lock);
  
  		skb = __first_packet_length(sk, rcvq, &total);
855846720   Eric Dumazet   udp: Fix udp_poll...
1543
  	}
e83c6744e   Eric Dumazet   udp: fix poll() i...
1544
  	res = skb ? skb->len : -1;
7c13f97ff   Paolo Abeni   udp: do fwd memor...
1545
  	if (total)
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1546
  		udp_rmem_release(sk, total, 1, false);
855846720   Eric Dumazet   udp: Fix udp_poll...
1547
  	spin_unlock_bh(&rcvq->lock);
855846720   Eric Dumazet   udp: Fix udp_poll...
1548
1549
  	return res;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
1551
1552
  /*
   *	IOCTL requests applicable to the UDP protocol
   */
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
1553

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
1555
  int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
  {
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1556
1557
  	switch (cmd) {
  	case SIOCOUTQ:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558
  	{
31e6d363a   Eric Dumazet   net: correct off-...
1559
  		int amount = sk_wmem_alloc_get(sk);
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1560
1561
  		return put_user(amount, (int __user *)arg);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1562

6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1563
1564
  	case SIOCINQ:
  	{
e83c6744e   Eric Dumazet   udp: fix poll() i...
1565
  		int amount = max_t(int, 0, first_packet_length(sk));
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1566

6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1567
1568
  		return put_user(amount, (int __user *)arg);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569

6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1570
1571
  	default:
  		return -ENOIOCTLCMD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1572
  	}
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
1573
1574
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
  }
c482c5685   Eric Dumazet   udp: cleanups
1576
  EXPORT_SYMBOL(udp_ioctl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577

2276f58ac   Paolo Abeni   udp: use a separa...
1578
  struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
fd69c399c   Paolo Abeni   datagram: remove ...
1579
  			       int noblock, int *off, int *err)
2276f58ac   Paolo Abeni   udp: use a separa...
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
  {
  	struct sk_buff_head *sk_queue = &sk->sk_receive_queue;
  	struct sk_buff_head *queue;
  	struct sk_buff *last;
  	long timeo;
  	int error;
  
  	queue = &udp_sk(sk)->reader_queue;
  	flags |= noblock ? MSG_DONTWAIT : 0;
  	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
  	do {
  		struct sk_buff *skb;
  
  		error = sock_error(sk);
  		if (error)
  			break;
  
  		error = -EAGAIN;
2276f58ac   Paolo Abeni   udp: use a separa...
1598
  		do {
2276f58ac   Paolo Abeni   udp: use a separa...
1599
1600
1601
  			spin_lock_bh(&queue->lock);
  			skb = __skb_try_recv_from_queue(sk, queue, flags,
  							udp_skb_destructor,
fd69c399c   Paolo Abeni   datagram: remove ...
1602
  							off, err, &last);
2276f58ac   Paolo Abeni   udp: use a separa...
1603
1604
  			if (skb) {
  				spin_unlock_bh(&queue->lock);
2276f58ac   Paolo Abeni   udp: use a separa...
1605
1606
  				return skb;
  			}
137a0dbe3   Eric Dumazet   udp: use skb_queu...
1607
  			if (skb_queue_empty_lockless(sk_queue)) {
2276f58ac   Paolo Abeni   udp: use a separa...
1608
1609
1610
  				spin_unlock_bh(&queue->lock);
  				goto busy_check;
  			}
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1611
1612
1613
1614
1615
  			/* refill the reader queue and walk it again
  			 * keep both queues locked to avoid re-acquiring
  			 * the sk_receive_queue lock if fwd memory scheduling
  			 * is needed.
  			 */
2276f58ac   Paolo Abeni   udp: use a separa...
1616
1617
  			spin_lock(&sk_queue->lock);
  			skb_queue_splice_tail_init(sk_queue, queue);
2276f58ac   Paolo Abeni   udp: use a separa...
1618
1619
  
  			skb = __skb_try_recv_from_queue(sk, queue, flags,
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1620
  							udp_skb_dtor_locked,
fd69c399c   Paolo Abeni   datagram: remove ...
1621
  							off, err, &last);
6dfb4367c   Paolo Abeni   udp: keep the sk_...
1622
  			spin_unlock(&sk_queue->lock);
2276f58ac   Paolo Abeni   udp: use a separa...
1623
  			spin_unlock_bh(&queue->lock);
de321ed38   Andrey Vagin   net: fix __skb_tr...
1624
  			if (skb)
2276f58ac   Paolo Abeni   udp: use a separa...
1625
  				return skb;
2276f58ac   Paolo Abeni   udp: use a separa...
1626
1627
1628
1629
1630
1631
  
  busy_check:
  			if (!sk_can_busy_loop(sk))
  				break;
  
  			sk_busy_loop(sk, flags & MSG_DONTWAIT);
137a0dbe3   Eric Dumazet   udp: use skb_queu...
1632
  		} while (!skb_queue_empty_lockless(sk_queue));
2276f58ac   Paolo Abeni   udp: use a separa...
1633
1634
1635
1636
1637
1638
1639
1640
1641
  
  		/* sk_queue is empty, reader_queue may contain peeked packets */
  	} while (timeo &&
  		 !__skb_wait_for_more_packets(sk, &error, &timeo,
  					      (struct sk_buff *)sk_queue));
  
  	*err = error;
  	return NULL;
  }
7e823644b   Jiri Kosina   udp: Unbreak modu...
1642
  EXPORT_SYMBOL(__skb_recv_udp);
2276f58ac   Paolo Abeni   udp: use a separa...
1643

db8dac20d   David S. Miller   [UDP]: Revert udp...
1644
1645
1646
1647
  /*
   * 	This should be easy, if there is something there we
   * 	return it, otherwise we block.
   */
1b7841404   Ying Xue   net: Remove iocb ...
1648
1649
  int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
  		int flags, int *addr_len)
db8dac20d   David S. Miller   [UDP]: Revert udp...
1650
1651
  {
  	struct inet_sock *inet = inet_sk(sk);
342dfc306   Steffen Hurrle   net: add build-ti...
1652
  	DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1653
  	struct sk_buff *skb;
59c2cdae2   David S. Miller   Revert "udp: remo...
1654
  	unsigned int ulen, copied;
fd69c399c   Paolo Abeni   datagram: remove ...
1655
  	int off, err, peeking = flags & MSG_PEEK;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1656
  	int is_udplite = IS_UDPLITE(sk);
197c949e7   Eric Dumazet   udp: properly sup...
1657
  	bool checksum_valid = false;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1658

db8dac20d   David S. Miller   [UDP]: Revert udp...
1659
  	if (flags & MSG_ERRQUEUE)
85fbaa750   Hannes Frederic Sowa   inet: fix addr_le...
1660
  		return ip_recv_error(sk, msg, len, addr_len);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1661
1662
  
  try_again:
a0917e0bc   Matthew Dawson   datagram: When pe...
1663
  	off = sk_peek_offset(sk, flags);
fd69c399c   Paolo Abeni   datagram: remove ...
1664
  	skb = __skb_recv_udp(sk, flags, noblock, &off, &err);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1665
  	if (!skb)
627d2d6b5   samanthakumar   udp: enable MSG_P...
1666
  		return err;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1667

b65ac4467   Paolo Abeni   udp: try to avoid...
1668
  	ulen = udp_skb_len(skb);
59c2cdae2   David S. Miller   Revert "udp: remo...
1669
  	copied = len;
627d2d6b5   samanthakumar   udp: enable MSG_P...
1670
1671
  	if (copied > ulen - off)
  		copied = ulen - off;
59c2cdae2   David S. Miller   Revert "udp: remo...
1672
  	else if (copied < ulen)
db8dac20d   David S. Miller   [UDP]: Revert udp...
1673
1674
1675
1676
1677
1678
1679
  		msg->msg_flags |= MSG_TRUNC;
  
  	/*
  	 * If checksum is needed at all, try to do it while copying the
  	 * data.  If the data is truncated, or if we only want a partial
  	 * coverage checksum (UDP-Lite), do it before the copy.
  	 */
d21dbdfe0   Eric Dumazet   udp: avoid one ca...
1680
1681
  	if (copied < ulen || peeking ||
  	    (is_udplite && UDP_SKB_CB(skb)->partial_cov)) {
b65ac4467   Paolo Abeni   udp: try to avoid...
1682
1683
  		checksum_valid = udp_skb_csum_unnecessary(skb) ||
  				!__udp_lib_checksum_complete(skb);
197c949e7   Eric Dumazet   udp: properly sup...
1684
  		if (!checksum_valid)
db8dac20d   David S. Miller   [UDP]: Revert udp...
1685
1686
  			goto csum_copy_err;
  	}
b65ac4467   Paolo Abeni   udp: try to avoid...
1687
1688
1689
1690
1691
1692
  	if (checksum_valid || udp_skb_csum_unnecessary(skb)) {
  		if (udp_skb_is_linear(skb))
  			err = copy_linear_skb(skb, copied, off, &msg->msg_iter);
  		else
  			err = skb_copy_datagram_msg(skb, off, msg, copied);
  	} else {
627d2d6b5   samanthakumar   udp: enable MSG_P...
1693
  		err = skb_copy_and_csum_datagram_msg(skb, off, msg);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1694
1695
1696
1697
  
  		if (err == -EINVAL)
  			goto csum_copy_err;
  	}
22911fc58   Eric Dumazet   net: skb_free_dat...
1698
  	if (unlikely(err)) {
fd69c399c   Paolo Abeni   datagram: remove ...
1699
  		if (!peeking) {
979402b16   Eric Dumazet   udp: increment UD...
1700
  			atomic_inc(&sk->sk_drops);
6aef70a85   Eric Dumazet   net: snmp: kill v...
1701
1702
  			UDP_INC_STATS(sock_net(sk),
  				      UDP_MIB_INERRORS, is_udplite);
979402b16   Eric Dumazet   udp: increment UD...
1703
  		}
850cbaddb   Paolo Abeni   udp: use it's own...
1704
  		kfree_skb(skb);
627d2d6b5   samanthakumar   udp: enable MSG_P...
1705
  		return err;
22911fc58   Eric Dumazet   net: skb_free_dat...
1706
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
1707

fd69c399c   Paolo Abeni   datagram: remove ...
1708
  	if (!peeking)
6aef70a85   Eric Dumazet   net: snmp: kill v...
1709
1710
  		UDP_INC_STATS(sock_net(sk),
  			      UDP_MIB_INDATAGRAMS, is_udplite);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1711

3b885787e   Neil Horman   net: Generalize s...
1712
  	sock_recv_ts_and_drops(msg, sk, skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1713
1714
  
  	/* Copy the address. */
c482c5685   Eric Dumazet   udp: cleanups
1715
  	if (sin) {
db8dac20d   David S. Miller   [UDP]: Revert udp...
1716
1717
1718
1719
  		sin->sin_family = AF_INET;
  		sin->sin_port = udp_hdr(skb)->source;
  		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
  		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
bceaa9024   Hannes Frederic Sowa   inet: prevent lea...
1720
  		*addr_len = sizeof(*sin);
983695fa6   Daniel Borkmann   bpf: fix unconnec...
1721
1722
1723
1724
  
  		if (cgroup_bpf_enabled)
  			BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk,
  							(struct sockaddr *)sin);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1725
  	}
bcd1665e3   Paolo Abeni   udp: add support ...
1726
1727
1728
  
  	if (udp_sk(sk)->gro_enabled)
  		udp_cmsg_recv(msg, sk, skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1729
  	if (inet->cmsg_flags)
ad959036a   Paolo Abeni   net/sock: add an ...
1730
  		ip_cmsg_recv_offset(msg, sk, skb, sizeof(struct udphdr), off);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1731

59c2cdae2   David S. Miller   Revert "udp: remo...
1732
  	err = copied;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1733
1734
  	if (flags & MSG_TRUNC)
  		err = ulen;
850cbaddb   Paolo Abeni   udp: use it's own...
1735
  	skb_consume_udp(sk, skb, peeking ? -err : err);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1736
1737
1738
  	return err;
  
  csum_copy_err:
2276f58ac   Paolo Abeni   udp: use a separa...
1739
1740
  	if (!__sk_queue_drop_skb(sk, &udp_sk(sk)->reader_queue, skb, flags,
  				 udp_skb_destructor)) {
6aef70a85   Eric Dumazet   net: snmp: kill v...
1741
1742
  		UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
  		UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
1743
  	}
850cbaddb   Paolo Abeni   udp: use it's own...
1744
  	kfree_skb(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1745

beb39db59   Eric Dumazet   udp: fix behavior...
1746
1747
  	/* starting over for a new packet, but check if we need to yield */
  	cond_resched();
9cfaa8def   Xufeng Zhang   udp/recvmsg: Clea...
1748
  	msg->msg_flags &= ~MSG_TRUNC;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1749
1750
  	goto try_again;
  }
d74bad4e7   Andrey Ignatov   bpf: Hooks for sy...
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
  int udp_pre_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
  {
  	/* This check is replicated from __ip4_datagram_connect() and
  	 * intended to prevent BPF program called below from accessing bytes
  	 * that are out of the bound specified by user in addr_len.
  	 */
  	if (addr_len < sizeof(struct sockaddr_in))
  		return -EINVAL;
  
  	return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr);
  }
  EXPORT_SYMBOL(udp_pre_connect);
286c72dea   Eric Dumazet   udp: must lock th...
1763
  int __udp_disconnect(struct sock *sk, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1764
1765
1766
1767
1768
  {
  	struct inet_sock *inet = inet_sk(sk);
  	/*
  	 *	1003.1g - break association.
  	 */
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
1769

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1770
  	sk->sk_state = TCP_CLOSE;
c720c7e83   Eric Dumazet   inet: rename some...
1771
1772
  	inet->inet_daddr = 0;
  	inet->inet_dport = 0;
bdeab9919   Tom Herbert   rps: Add flag to ...
1773
  	sock_rps_reset_rxhash(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1774
  	sk->sk_bound_dev_if = 0;
e72258bf6   Willem de Bruijn   udp: rehash on di...
1775
  	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1776
  		inet_reset_saddr(sk);
e72258bf6   Willem de Bruijn   udp: rehash on di...
1777
1778
1779
1780
  		if (sk->sk_prot->rehash &&
  		    (sk->sk_userlocks & SOCK_BINDPORT_LOCK))
  			sk->sk_prot->rehash(sk);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781
1782
1783
  
  	if (!(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) {
  		sk->sk_prot->unhash(sk);
c720c7e83   Eric Dumazet   inet: rename some...
1784
  		inet->inet_sport = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1785
1786
1787
1788
  	}
  	sk_dst_reset(sk);
  	return 0;
  }
286c72dea   Eric Dumazet   udp: must lock th...
1789
1790
1791
1792
1793
1794
1795
1796
1797
  EXPORT_SYMBOL(__udp_disconnect);
  
  int udp_disconnect(struct sock *sk, int flags)
  {
  	lock_sock(sk);
  	__udp_disconnect(sk, flags);
  	release_sock(sk);
  	return 0;
  }
c482c5685   Eric Dumazet   udp: cleanups
1798
  EXPORT_SYMBOL(udp_disconnect);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799

645ca708f   Eric Dumazet   udp: introduce st...
1800
1801
  void udp_lib_unhash(struct sock *sk)
  {
723b46108   Eric Dumazet   net: udp_unhash()...
1802
1803
  	if (sk_hashed(sk)) {
  		struct udp_table *udptable = sk->sk_prot->h.udp_table;
512615b6b   Eric Dumazet   udp: secondary ha...
1804
1805
1806
1807
1808
  		struct udp_hslot *hslot, *hslot2;
  
  		hslot  = udp_hashslot(udptable, sock_net(sk),
  				      udp_sk(sk)->udp_port_hash);
  		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
645ca708f   Eric Dumazet   udp: introduce st...
1809

723b46108   Eric Dumazet   net: udp_unhash()...
1810
  		spin_lock_bh(&hslot->lock);
e32ea7e74   Craig Gallek   soreuseport: fast...
1811
1812
  		if (rcu_access_pointer(sk->sk_reuseport_cb))
  			reuseport_detach_sock(sk);
ca065d0cf   Eric Dumazet   udp: no longer us...
1813
  		if (sk_del_node_init_rcu(sk)) {
fdcc8aa95   Eric Dumazet   udp: add a counte...
1814
  			hslot->count--;
c720c7e83   Eric Dumazet   inet: rename some...
1815
  			inet_sk(sk)->inet_num = 0;
723b46108   Eric Dumazet   net: udp_unhash()...
1816
  			sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
512615b6b   Eric Dumazet   udp: secondary ha...
1817
1818
  
  			spin_lock(&hslot2->lock);
ca065d0cf   Eric Dumazet   udp: no longer us...
1819
  			hlist_del_init_rcu(&udp_sk(sk)->udp_portaddr_node);
512615b6b   Eric Dumazet   udp: secondary ha...
1820
1821
  			hslot2->count--;
  			spin_unlock(&hslot2->lock);
723b46108   Eric Dumazet   net: udp_unhash()...
1822
1823
  		}
  		spin_unlock_bh(&hslot->lock);
645ca708f   Eric Dumazet   udp: introduce st...
1824
  	}
645ca708f   Eric Dumazet   udp: introduce st...
1825
1826
  }
  EXPORT_SYMBOL(udp_lib_unhash);
719f83585   Eric Dumazet   udp: add rehash o...
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
  /*
   * inet_rcv_saddr was changed, we must rehash secondary hash
   */
  void udp_lib_rehash(struct sock *sk, u16 newhash)
  {
  	if (sk_hashed(sk)) {
  		struct udp_table *udptable = sk->sk_prot->h.udp_table;
  		struct udp_hslot *hslot, *hslot2, *nhslot2;
  
  		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
  		nhslot2 = udp_hashslot2(udptable, newhash);
  		udp_sk(sk)->udp_portaddr_hash = newhash;
e32ea7e74   Craig Gallek   soreuseport: fast...
1839
1840
1841
  
  		if (hslot2 != nhslot2 ||
  		    rcu_access_pointer(sk->sk_reuseport_cb)) {
719f83585   Eric Dumazet   udp: add rehash o...
1842
1843
1844
1845
  			hslot = udp_hashslot(udptable, sock_net(sk),
  					     udp_sk(sk)->udp_port_hash);
  			/* we must lock primary chain too */
  			spin_lock_bh(&hslot->lock);
e32ea7e74   Craig Gallek   soreuseport: fast...
1846
1847
1848
1849
1850
  			if (rcu_access_pointer(sk->sk_reuseport_cb))
  				reuseport_detach_sock(sk);
  
  			if (hslot2 != nhslot2) {
  				spin_lock(&hslot2->lock);
ca065d0cf   Eric Dumazet   udp: no longer us...
1851
  				hlist_del_init_rcu(&udp_sk(sk)->udp_portaddr_node);
e32ea7e74   Craig Gallek   soreuseport: fast...
1852
1853
1854
1855
  				hslot2->count--;
  				spin_unlock(&hslot2->lock);
  
  				spin_lock(&nhslot2->lock);
ca065d0cf   Eric Dumazet   udp: no longer us...
1856
  				hlist_add_head_rcu(&udp_sk(sk)->udp_portaddr_node,
e32ea7e74   Craig Gallek   soreuseport: fast...
1857
1858
1859
1860
  							 &nhslot2->head);
  				nhslot2->count++;
  				spin_unlock(&nhslot2->lock);
  			}
719f83585   Eric Dumazet   udp: add rehash o...
1861
1862
1863
1864
1865
1866
  
  			spin_unlock_bh(&hslot->lock);
  		}
  	}
  }
  EXPORT_SYMBOL(udp_lib_rehash);
8f6b53928   Alexey Kodanev   udp: add missing ...
1867
  void udp_v4_rehash(struct sock *sk)
719f83585   Eric Dumazet   udp: add rehash o...
1868
  {
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
1869
  	u16 new_hash = ipv4_portaddr_hash(sock_net(sk),
719f83585   Eric Dumazet   udp: add rehash o...
1870
1871
1872
1873
  					  inet_sk(sk)->inet_rcv_saddr,
  					  inet_sk(sk)->inet_num);
  	udp_lib_rehash(sk, new_hash);
  }
a3f96c47c   Paolo Abeni   udp: make *udp*_q...
1874
  static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
93821778d   Herbert Xu   udp: Fix rcv sock...
1875
  {
fec5e652e   Tom Herbert   rfs: Receive Flow...
1876
  	int rc;
766e9037c   Eric Dumazet   net: sk_drops con...
1877

005ec9743   Shawn Bohrer   udp: Only allow b...
1878
  	if (inet_sk(sk)->inet_daddr) {
bdeab9919   Tom Herbert   rps: Add flag to ...
1879
  		sock_rps_save_rxhash(sk, skb);
005ec9743   Shawn Bohrer   udp: Only allow b...
1880
  		sk_mark_napi_id(sk, skb);
2c8c56e15   Eric Dumazet   net: introduce SO...
1881
  		sk_incoming_cpu_update(sk);
e68b6e50f   Eric Dumazet   udp: enable busy ...
1882
1883
  	} else {
  		sk_mark_napi_id_once(sk, skb);
005ec9743   Shawn Bohrer   udp: Only allow b...
1884
  	}
fec5e652e   Tom Herbert   rfs: Receive Flow...
1885

850cbaddb   Paolo Abeni   udp: use it's own...
1886
  	rc = __udp_enqueue_schedule_skb(sk, skb);
766e9037c   Eric Dumazet   net: sk_drops con...
1887
1888
  	if (rc < 0) {
  		int is_udplite = IS_UDPLITE(sk);
93821778d   Herbert Xu   udp: Fix rcv sock...
1889

93821778d   Herbert Xu   udp: Fix rcv sock...
1890
  		/* Note that an ENOMEM error is charged twice */
766e9037c   Eric Dumazet   net: sk_drops con...
1891
  		if (rc == -ENOMEM)
e61da9e25   Eric Dumazet   udp: prepare for ...
1892
  			UDP_INC_STATS(sock_net(sk), UDP_MIB_RCVBUFERRORS,
02c223470   Eric Dumazet   net: udp: rename ...
1893
  					is_udplite);
e61da9e25   Eric Dumazet   udp: prepare for ...
1894
  		UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
766e9037c   Eric Dumazet   net: sk_drops con...
1895
  		kfree_skb(skb);
296f7ea75   Satoru Moriya   udp: add tracepoi...
1896
  		trace_udp_fail_queue_rcv_skb(rc, sk);
766e9037c   Eric Dumazet   net: sk_drops con...
1897
  		return -1;
93821778d   Herbert Xu   udp: Fix rcv sock...
1898
1899
1900
  	}
  
  	return 0;
93821778d   Herbert Xu   udp: Fix rcv sock...
1901
  }
db8dac20d   David S. Miller   [UDP]: Revert udp...
1902
1903
1904
1905
1906
1907
1908
1909
  /* returns:
   *  -1: error
   *   0: success
   *  >0: "udp encap" protocol resubmission
   *
   * Note that in the success and error cases, the skb is assumed to
   * have either been requeued or freed.
   */
cf329aa42   Paolo Abeni   udp: cope with UD...
1910
  static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
db8dac20d   David S. Miller   [UDP]: Revert udp...
1911
1912
  {
  	struct udp_sock *up = udp_sk(sk);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1913
1914
1915
1916
1917
1918
1919
  	int is_udplite = IS_UDPLITE(sk);
  
  	/*
  	 *	Charge it to the socket, dropping if the queue is full.
  	 */
  	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
  		goto drop;
895b5c9f2   Florian Westphal   netfilter: drop b...
1920
  	nf_reset_ct(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1921

88ab31081   Davidlohr Bueso   net/udp: Update u...
1922
  	if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) {
0ad92ad03   Eric Dumazet   udp: fix a race i...
1923
  		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
  		/*
  		 * This is an encapsulation socket so pass the skb to
  		 * the socket's udp_encap_rcv() hook. Otherwise, just
  		 * fall through and pass this up the UDP socket.
  		 * up->encap_rcv() returns the following value:
  		 * =0 if skb was successfully passed to the encap
  		 *    handler or was discarded by it.
  		 * >0 if skb should be passed on to UDP.
  		 * <0 if skb should be resubmitted as proto -N
  		 */
  
  		/* if we're overly short, let UDP handle it */
6aa7de059   Mark Rutland   locking/atomics: ...
1936
  		encap_rcv = READ_ONCE(up->encap_rcv);
e5aed006b   Hannes Frederic Sowa   udp: prevent skbs...
1937
  		if (encap_rcv) {
db8dac20d   David S. Miller   [UDP]: Revert udp...
1938
  			int ret;
0a80966b1   Tom Herbert   net: Verify UDP c...
1939
1940
1941
  			/* Verify checksum before giving to encap */
  			if (udp_lib_checksum_complete(skb))
  				goto csum_error;
0ad92ad03   Eric Dumazet   udp: fix a race i...
1942
  			ret = encap_rcv(sk, skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1943
  			if (ret <= 0) {
02c223470   Eric Dumazet   net: udp: rename ...
1944
1945
1946
  				__UDP_INC_STATS(sock_net(sk),
  						UDP_MIB_INDATAGRAMS,
  						is_udplite);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
  				return -ret;
  			}
  		}
  
  		/* FALLTHROUGH -- it's a UDP Packet */
  	}
  
  	/*
  	 * 	UDP-Lite specific tests, ignored on UDP sockets
  	 */
  	if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
  
  		/*
  		 * MIB statistics other than incrementing the error count are
  		 * disabled for the following two types of errors: these depend
  		 * on the application settings, not on the functioning of the
  		 * protocol stack as such.
  		 *
  		 * RFC 3828 here recommends (sec 3.3): "There should also be a
  		 * way ... to ... at least let the receiving application block
  		 * delivery of packets with coverage values less than a value
  		 * provided by the application."
  		 */
  		if (up->pcrlen == 0) {          /* full coverage was set  */
ba7a46f16   Joe Perches   net: Convert LIMI...
1971
1972
1973
  			net_dbg_ratelimited("UDPLite: partial coverage %d while full coverage %d requested
  ",
  					    UDP_SKB_CB(skb)->cscov, skb->len);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1974
1975
1976
1977
1978
1979
1980
1981
1982
  			goto drop;
  		}
  		/* The next case involves violating the min. coverage requested
  		 * by the receiver. This is subtle: if receiver wants x and x is
  		 * greater than the buffersize/MTU then receiver will complain
  		 * that it wants x while sender emits packets of smaller size y.
  		 * Therefore the above ...()->partial_cov statement is essential.
  		 */
  		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
ba7a46f16   Joe Perches   net: Convert LIMI...
1983
1984
1985
  			net_dbg_ratelimited("UDPLite: coverage %d too small, need min %d
  ",
  					    UDP_SKB_CB(skb)->cscov, up->pcrlen);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1986
1987
1988
  			goto drop;
  		}
  	}
dd99e425b   Paolo Abeni   udp: prefetch rme...
1989
  	prefetch(&sk->sk_rmem_alloc);
ce25d66ad   Eric Dumazet   Possible problem ...
1990
1991
  	if (rcu_access_pointer(sk->sk_filter) &&
  	    udp_lib_checksum_complete(skb))
e6afc8ace   samanthakumar   udp: remove heade...
1992
  			goto csum_error;
ce25d66ad   Eric Dumazet   Possible problem ...
1993

ba66bbe54   Daniel Borkmann   udp: use sk_filte...
1994
  	if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr)))
a61276977   Michal Kubeček   udp: prevent bugc...
1995
  		goto drop;
db8dac20d   David S. Miller   [UDP]: Revert udp...
1996

e6afc8ace   samanthakumar   udp: remove heade...
1997
  	udp_csum_pull_header(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
1998

fbf8866d6   Shawn Bohrer   net: ipv4 only po...
1999
  	ipv4_pktinfo_prepare(sk, skb);
850cbaddb   Paolo Abeni   udp: use it's own...
2000
  	return __udp_queue_rcv_skb(sk, skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2001

6a5dc9e59   Eric Dumazet   net: Add MIB coun...
2002
  csum_error:
02c223470   Eric Dumazet   net: udp: rename ...
2003
  	__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2004
  drop:
02c223470   Eric Dumazet   net: udp: rename ...
2005
  	__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
8edf19c2f   Eric Dumazet   net: sk_drops con...
2006
  	atomic_inc(&sk->sk_drops);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2007
2008
2009
  	kfree_skb(skb);
  	return -1;
  }
cf329aa42   Paolo Abeni   udp: cope with UD...
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
  static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
  {
  	struct sk_buff *next, *segs;
  	int ret;
  
  	if (likely(!udp_unexpected_gso(sk, skb)))
  		return udp_queue_rcv_one_skb(sk, skb);
  
  	BUILD_BUG_ON(sizeof(struct udp_skb_cb) > SKB_SGO_CB_OFFSET);
  	__skb_push(skb, -skb_mac_offset(skb));
  	segs = udp_rcv_segment(sk, skb, true);
  	for (skb = segs; skb; skb = next) {
  		next = skb->next;
  		__skb_pull(skb, skb_transport_offset(skb));
  		ret = udp_queue_rcv_one_skb(sk, skb);
  		if (ret > 0)
  			ip_protocol_deliver_rcu(dev_net(skb->dev), skb, -ret);
  	}
  	return 0;
  }
975022310   Eric Dumazet   udp: ipv4: must a...
2030
  /* For TCP sockets, sk_rx_dst is protected by socket lock
e47eb5dfb   Eric Dumazet   udp: ipv4: do not...
2031
   * For UDP, we use xchg() to guard against concurrent changes.
975022310   Eric Dumazet   udp: ipv4: must a...
2032
   */
64f0f5d18   Paolo Abeni   udp6: set rx_dst_...
2033
  bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2034
  {
975022310   Eric Dumazet   udp: ipv4: must a...
2035
  	struct dst_entry *old;
d24406c85   Wei Wang   udp: call dst_hol...
2036
2037
2038
  	if (dst_hold_safe(dst)) {
  		old = xchg(&sk->sk_rx_dst, dst);
  		dst_release(old);
64f0f5d18   Paolo Abeni   udp6: set rx_dst_...
2039
  		return old != dst;
d24406c85   Wei Wang   udp: call dst_hol...
2040
  	}
64f0f5d18   Paolo Abeni   udp6: set rx_dst_...
2041
  	return false;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2042
  }
c9f2c1ae1   Paolo Abeni   udp6: fix socket ...
2043
  EXPORT_SYMBOL(udp_sk_rx_dst_set);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2044

db8dac20d   David S. Miller   [UDP]: Revert udp...
2045
2046
2047
  /*
   *	Multicasts and broadcasts go to each listener.
   *
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2048
   *	Note: called only from the BH handler context.
db8dac20d   David S. Miller   [UDP]: Revert udp...
2049
   */
e31634931   Pavel Emelyanov   udp: provide a st...
2050
  static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2051
2052
  				    struct udphdr  *uh,
  				    __be32 saddr, __be32 daddr,
36cbb2452   Rick Jones   udp: Increment UD...
2053
2054
  				    struct udp_table *udptable,
  				    int proto)
db8dac20d   David S. Miller   [UDP]: Revert udp...
2055
  {
ca065d0cf   Eric Dumazet   udp: no longer us...
2056
  	struct sock *sk, *first = NULL;
5cf3d4619   David Held   udp: Simplify __u...
2057
2058
  	unsigned short hnum = ntohs(uh->dest);
  	struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum);
2dc41cff7   David Held   udp: Use hash2 fo...
2059
  	unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
ca065d0cf   Eric Dumazet   udp: no longer us...
2060
2061
  	unsigned int offset = offsetof(typeof(*sk), sk_node);
  	int dif = skb->dev->ifindex;
fb74c2773   David Ahern   net: ipv4: add se...
2062
  	int sdif = inet_sdif(skb);
ca065d0cf   Eric Dumazet   udp: no longer us...
2063
2064
  	struct hlist_node *node;
  	struct sk_buff *nskb;
2dc41cff7   David Held   udp: Use hash2 fo...
2065
2066
  
  	if (use_hash2) {
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
2067
  		hash2_any = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum) &
73e2d5e34   Pablo Neira   udp: restore UDPl...
2068
  			    udptable->mask;
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
2069
  		hash2 = ipv4_portaddr_hash(net, daddr, hnum) & udptable->mask;
2dc41cff7   David Held   udp: Use hash2 fo...
2070
  start_lookup:
73e2d5e34   Pablo Neira   udp: restore UDPl...
2071
  		hslot = &udptable->hash2[hash2];
2dc41cff7   David Held   udp: Use hash2 fo...
2072
2073
  		offset = offsetof(typeof(*sk), __sk_common.skc_portaddr_node);
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
2074

ca065d0cf   Eric Dumazet   udp: no longer us...
2075
2076
  	sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
  		if (!__udp_is_mcast_sock(net, sk, uh->dest, daddr,
fb74c2773   David Ahern   net: ipv4: add se...
2077
  					 uh->source, saddr, dif, sdif, hnum))
ca065d0cf   Eric Dumazet   udp: no longer us...
2078
2079
2080
2081
2082
  			continue;
  
  		if (!first) {
  			first = sk;
  			continue;
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2083
  		}
ca065d0cf   Eric Dumazet   udp: no longer us...
2084
  		nskb = skb_clone(skb, GFP_ATOMIC);
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2085

ca065d0cf   Eric Dumazet   udp: no longer us...
2086
2087
  		if (unlikely(!nskb)) {
  			atomic_inc(&sk->sk_drops);
02c223470   Eric Dumazet   net: udp: rename ...
2088
2089
2090
2091
  			__UDP_INC_STATS(net, UDP_MIB_RCVBUFERRORS,
  					IS_UDPLITE(sk));
  			__UDP_INC_STATS(net, UDP_MIB_INERRORS,
  					IS_UDPLITE(sk));
ca065d0cf   Eric Dumazet   udp: no longer us...
2092
2093
2094
2095
2096
  			continue;
  		}
  		if (udp_queue_rcv_skb(sk, nskb) > 0)
  			consume_skb(nskb);
  	}
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2097

2dc41cff7   David Held   udp: Use hash2 fo...
2098
2099
2100
2101
2102
  	/* Also lookup *:port if we are using hash2 and haven't done so yet. */
  	if (use_hash2 && hash2 != hash2_any) {
  		hash2 = hash2_any;
  		goto start_lookup;
  	}
ca065d0cf   Eric Dumazet   udp: no longer us...
2103
2104
2105
  	if (first) {
  		if (udp_queue_rcv_skb(first, skb) > 0)
  			consume_skb(skb);
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2106
  	} else {
ca065d0cf   Eric Dumazet   udp: no longer us...
2107
  		kfree_skb(skb);
02c223470   Eric Dumazet   net: udp: rename ...
2108
2109
  		__UDP_INC_STATS(net, UDP_MIB_IGNOREDMULTI,
  				proto == IPPROTO_UDPLITE);
1240d1373   Eric Dumazet   ipv4: udp: Optimi...
2110
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
2111
2112
2113
2114
2115
  	return 0;
  }
  
  /* Initialize UDP checksum. If exited with zero value (success),
   * CHECKSUM_UNNECESSARY means, that no more checks are required.
666a3d6e1   Su Yanjun   udp: Fix typo in ...
2116
   * Otherwise, csum completion requires checksumming packet body,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2117
2118
2119
2120
2121
   * including udp header and folding it to skb->csum.
   */
  static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
  				 int proto)
  {
db8dac20d   David S. Miller   [UDP]: Revert udp...
2122
2123
2124
2125
2126
2127
2128
2129
2130
  	int err;
  
  	UDP_SKB_CB(skb)->partial_cov = 0;
  	UDP_SKB_CB(skb)->cscov = skb->len;
  
  	if (proto == IPPROTO_UDPLITE) {
  		err = udplite_checksum_init(skb, uh);
  		if (err)
  			return err;
15f35d49c   Alexey Kodanev   udplite: fix part...
2131
2132
2133
2134
2135
  
  		if (UDP_SKB_CB(skb)->partial_cov) {
  			skb->csum = inet_compute_pseudo(skb, proto);
  			return 0;
  		}
db8dac20d   David S. Miller   [UDP]: Revert udp...
2136
  	}
b46d9f625   Hannes Frederic Sowa   ipv4: fix checksu...
2137
2138
2139
  	/* Note, we are only interested in != 0 or == 0, thus the
  	 * force to int.
  	 */
db4f1be3c   Sean Tranchetti   net: udp: fix han...
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
  	err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
  							inet_compute_pseudo);
  	if (err)
  		return err;
  
  	if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) {
  		/* If SW calculated the value, we know it's bad */
  		if (skb->csum_complete_sw)
  			return 1;
  
  		/* HW says the value is bad. Let's validate that.
  		 * skb->csum is no longer the full packet checksum,
  		 * so don't treat it as such.
  		 */
  		skb_checksum_complete_unset(skb);
  	}
  
  	return 0;
db8dac20d   David S. Miller   [UDP]: Revert udp...
2158
  }
2b5a92174   Paolo Abeni   udp4: fix IP_CMSG...
2159
2160
2161
2162
2163
2164
2165
2166
2167
  /* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
   * return code conversion for ip layer consumption
   */
  static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
  			       struct udphdr *uh)
  {
  	int ret;
  
  	if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
e4aa33ad5   Li RongQing   net: remove unuse...
2168
  		skb_checksum_try_convert(skb, IPPROTO_UDP, inet_compute_pseudo);
2b5a92174   Paolo Abeni   udp4: fix IP_CMSG...
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
  
  	ret = udp_queue_rcv_skb(sk, skb);
  
  	/* a return value > 0 means to resubmit the input, but
  	 * it wants the return to be -protocol, or 0
  	 */
  	if (ret > 0)
  		return -ret;
  	return 0;
  }
db8dac20d   David S. Miller   [UDP]: Revert udp...
2179
2180
2181
  /*
   *	All we need to do is get the socket, and then do a checksum.
   */
645ca708f   Eric Dumazet   udp: introduce st...
2182
  int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2183
2184
2185
  		   int proto)
  {
  	struct sock *sk;
7b5e56f9d   Jesper Dangaard Brouer   udp: Fix UDP shor...
2186
  	struct udphdr *uh;
db8dac20d   David S. Miller   [UDP]: Revert udp...
2187
  	unsigned short ulen;
adf30907d   Eric Dumazet   net: skb->dst acc...
2188
  	struct rtable *rt = skb_rtable(skb);
2783ef231   Jesper Dangaard Brouer   udp: Fix potentia...
2189
  	__be32 saddr, daddr;
0283328e2   Pavel Emelyanov   MIB: add struct n...
2190
  	struct net *net = dev_net(skb->dev);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2191
2192
2193
2194
2195
2196
  
  	/*
  	 *  Validate the packet.
  	 */
  	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
  		goto drop;		/* No space for header. */
7b5e56f9d   Jesper Dangaard Brouer   udp: Fix UDP shor...
2197
  	uh   = udp_hdr(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2198
  	ulen = ntohs(uh->len);
ccc2d97cb   Bjørn Mork   ipv4: udp: fix sh...
2199
2200
  	saddr = ip_hdr(skb)->saddr;
  	daddr = ip_hdr(skb)->daddr;
db8dac20d   David S. Miller   [UDP]: Revert udp...
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
  	if (ulen > skb->len)
  		goto short_packet;
  
  	if (proto == IPPROTO_UDP) {
  		/* UDP validates ulen. */
  		if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
  			goto short_packet;
  		uh = udp_hdr(skb);
  	}
  
  	if (udp4_csum_init(skb, uh, proto))
  		goto csum_error;
8afdd99a1   Eric Dumazet   udp: ipv4: fix an...
2213
2214
  	sk = skb_steal_sock(skb);
  	if (sk) {
975022310   Eric Dumazet   udp: ipv4: must a...
2215
  		struct dst_entry *dst = skb_dst(skb);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2216
  		int ret;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2217

975022310   Eric Dumazet   udp: ipv4: must a...
2218
2219
  		if (unlikely(sk->sk_rx_dst != dst))
  			udp_sk_rx_dst_set(sk, dst);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2220

2b5a92174   Paolo Abeni   udp4: fix IP_CMSG...
2221
  		ret = udp_unicast_rcv_skb(sk, skb, uh);
8afdd99a1   Eric Dumazet   udp: ipv4: fix an...
2222
  		sock_put(sk);
2b5a92174   Paolo Abeni   udp4: fix IP_CMSG...
2223
  		return ret;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2224
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
2225

c18450a52   Fabian Frederick   udp: remove else ...
2226
2227
  	if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
  		return __udp4_lib_mcast_deliver(net, skb, uh,
36cbb2452   Rick Jones   udp: Increment UD...
2228
  						saddr, daddr, udptable, proto);
c18450a52   Fabian Frederick   udp: remove else ...
2229
2230
  
  	sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
2b5a92174   Paolo Abeni   udp4: fix IP_CMSG...
2231
2232
  	if (sk)
  		return udp_unicast_rcv_skb(sk, skb, uh);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2233
2234
2235
  
  	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
  		goto drop;
895b5c9f2   Florian Westphal   netfilter: drop b...
2236
  	nf_reset_ct(skb);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2237
2238
2239
2240
  
  	/* No socket. Drop packet silently, if checksum is wrong */
  	if (udp_lib_checksum_complete(skb))
  		goto csum_error;
02c223470   Eric Dumazet   net: udp: rename ...
2241
  	__UDP_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
  	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
  
  	/*
  	 * Hmm.  We got an UDP packet to a port to which we
  	 * don't wanna listen.  Ignore it.
  	 */
  	kfree_skb(skb);
  	return 0;
  
  short_packet:
ba7a46f16   Joe Perches   net: Convert LIMI...
2252
2253
2254
2255
2256
2257
  	net_dbg_ratelimited("UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u
  ",
  			    proto == IPPROTO_UDPLITE ? "Lite" : "",
  			    &saddr, ntohs(uh->source),
  			    ulen, skb->len,
  			    &daddr, ntohs(uh->dest));
db8dac20d   David S. Miller   [UDP]: Revert udp...
2258
2259
2260
2261
2262
2263
2264
  	goto drop;
  
  csum_error:
  	/*
  	 * RFC1122: OK.  Discards the bad packet silently (as far as
  	 * the network is concerned, anyway) as per 4.1.3.4 (MUST).
  	 */
ba7a46f16   Joe Perches   net: Convert LIMI...
2265
2266
2267
2268
2269
  	net_dbg_ratelimited("UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d
  ",
  			    proto == IPPROTO_UDPLITE ? "Lite" : "",
  			    &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest),
  			    ulen);
02c223470   Eric Dumazet   net: udp: rename ...
2270
  	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2271
  drop:
02c223470   Eric Dumazet   net: udp: rename ...
2272
  	__UDP_INC_STATS(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2273
2274
2275
  	kfree_skb(skb);
  	return 0;
  }
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2276
2277
2278
2279
2280
2281
  /* We can only early demux multicast if there is a single matching socket.
   * If more than one socket found returns NULL
   */
  static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
  						  __be16 loc_port, __be32 loc_addr,
  						  __be16 rmt_port, __be32 rmt_addr,
fb74c2773   David Ahern   net: ipv4: add se...
2282
  						  int dif, int sdif)
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2283
2284
  {
  	struct sock *sk, *result;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2285
  	unsigned short hnum = ntohs(loc_port);
ca065d0cf   Eric Dumazet   udp: no longer us...
2286
  	unsigned int slot = udp_hashfn(net, hnum, udp_table.mask);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2287
  	struct udp_hslot *hslot = &udp_table.hash[slot];
63c6f81cd   Eric Dumazet   udp: ipv4: do not...
2288
2289
2290
  	/* Do not bother scanning a too big list */
  	if (hslot->count > 10)
  		return NULL;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2291
  	result = NULL;
ca065d0cf   Eric Dumazet   udp: no longer us...
2292
2293
  	sk_for_each_rcu(sk, &hslot->head) {
  		if (__udp_is_mcast_sock(net, sk, loc_port, loc_addr,
fb74c2773   David Ahern   net: ipv4: add se...
2294
  					rmt_port, rmt_addr, dif, sdif, hnum)) {
ca065d0cf   Eric Dumazet   udp: no longer us...
2295
2296
  			if (result)
  				return NULL;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2297
  			result = sk;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2298
2299
  		}
  	}
ca065d0cf   Eric Dumazet   udp: no longer us...
2300

421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
  	return result;
  }
  
  /* For unicast we should only early demux connected sockets or we can
   * break forwarding setups.  The chains here can be long so only check
   * if the first socket is an exact match and if not move on.
   */
  static struct sock *__udp4_lib_demux_lookup(struct net *net,
  					    __be16 loc_port, __be32 loc_addr,
  					    __be16 rmt_port, __be32 rmt_addr,
3fa6f616a   David Ahern   net: ipv4: add se...
2311
  					    int dif, int sdif)
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2312
  {
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2313
  	unsigned short hnum = ntohs(loc_port);
f0b1e64c1   Martin KaFai Lau   udp: Move udp[46]...
2314
  	unsigned int hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2315
2316
  	unsigned int slot2 = hash2 & udp_table.mask;
  	struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
c72283174   Joe Perches   net: Use a more s...
2317
  	INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2318
  	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
ca065d0cf   Eric Dumazet   udp: no longer us...
2319
  	struct sock *sk;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2320

ca065d0cf   Eric Dumazet   udp: no longer us...
2321
2322
  	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
  		if (INET_MATCH(sk, net, acookie, rmt_addr,
3fa6f616a   David Ahern   net: ipv4: add se...
2323
  			       loc_addr, ports, dif, sdif))
ca065d0cf   Eric Dumazet   udp: no longer us...
2324
  			return sk;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2325
2326
2327
  		/* Only check first socket in chain */
  		break;
  	}
ca065d0cf   Eric Dumazet   udp: no longer us...
2328
  	return NULL;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2329
  }
7487449c8   Paolo Abeni   IPv4: early demux...
2330
  int udp_v4_early_demux(struct sk_buff *skb)
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2331
  {
610438b74   Eric Dumazet   udp: ipv4: fix po...
2332
  	struct net *net = dev_net(skb->dev);
bc044e8db   Paolo Abeni   udp: perform sour...
2333
  	struct in_device *in_dev = NULL;
610438b74   Eric Dumazet   udp: ipv4: fix po...
2334
2335
  	const struct iphdr *iph;
  	const struct udphdr *uh;
ca065d0cf   Eric Dumazet   udp: no longer us...
2336
  	struct sock *sk = NULL;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2337
  	struct dst_entry *dst;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2338
  	int dif = skb->dev->ifindex;
fb74c2773   David Ahern   net: ipv4: add se...
2339
  	int sdif = inet_sdif(skb);
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
2340
  	int ours;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2341
2342
2343
  
  	/* validate the packet */
  	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))
7487449c8   Paolo Abeni   IPv4: early demux...
2344
  		return 0;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2345

610438b74   Eric Dumazet   udp: ipv4: fix po...
2346
2347
  	iph = ip_hdr(skb);
  	uh = udp_hdr(skb);
996b44fce   Paolo Abeni   udp: fix bcast pa...
2348
  	if (skb->pkt_type == PACKET_MULTICAST) {
bc044e8db   Paolo Abeni   udp: perform sour...
2349
  		in_dev = __in_dev_get_rcu(skb->dev);
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
2350
2351
  
  		if (!in_dev)
7487449c8   Paolo Abeni   IPv4: early demux...
2352
  			return 0;
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
2353

996b44fce   Paolo Abeni   udp: fix bcast pa...
2354
2355
2356
2357
  		ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
  				       iph->protocol);
  		if (!ours)
  			return 0;
ad0ea1989   Paolo Abeni   ipv4: fix broadca...
2358

421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2359
  		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
fb74c2773   David Ahern   net: ipv4: add se...
2360
2361
  						   uh->source, iph->saddr,
  						   dif, sdif);
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
2362
  	} else if (skb->pkt_type == PACKET_HOST) {
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2363
  		sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
3fa6f616a   David Ahern   net: ipv4: add se...
2364
  					     uh->source, iph->saddr, dif, sdif);
6e5403093   Shawn Bohrer   ipv4/udp: Verify ...
2365
  	}
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2366

41c6d650f   Reshetova, Elena   net: convert sock...
2367
  	if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt))
7487449c8   Paolo Abeni   IPv4: early demux...
2368
  		return 0;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2369
2370
  
  	skb->sk = sk;
82eabd9eb   Alexander Duyck   net: merge cases ...
2371
  	skb->destructor = sock_efree;
10e2eb878   Eric Dumazet   udp: fix dst race...
2372
  	dst = READ_ONCE(sk->sk_rx_dst);
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2373
2374
2375
  
  	if (dst)
  		dst = dst_check(dst, 0);
10e2eb878   Eric Dumazet   udp: fix dst race...
2376
  	if (dst) {
bc044e8db   Paolo Abeni   udp: perform sour...
2377
  		u32 itag = 0;
d24406c85   Wei Wang   udp: call dst_hol...
2378
2379
2380
2381
2382
  		/* set noref for now.
  		 * any place which wants to hold dst has to call
  		 * dst_hold_safe()
  		 */
  		skb_dst_set_noref(skb, dst);
bc044e8db   Paolo Abeni   udp: perform sour...
2383
2384
2385
2386
2387
2388
2389
2390
  
  		/* for unconnected multicast sockets we need to validate
  		 * the source on each packet
  		 */
  		if (!inet_sk(sk)->inet_daddr && in_dev)
  			return ip_mc_validate_source(skb, iph->daddr,
  						     iph->saddr, iph->tos,
  						     skb->dev, in_dev, &itag);
10e2eb878   Eric Dumazet   udp: fix dst race...
2391
  	}
7487449c8   Paolo Abeni   IPv4: early demux...
2392
  	return 0;
421b3885b   Shawn Bohrer   udp: ipv4: Add ud...
2393
  }
db8dac20d   David S. Miller   [UDP]: Revert udp...
2394
2395
  int udp_rcv(struct sk_buff *skb)
  {
645ca708f   Eric Dumazet   udp: introduce st...
2396
  	return __udp4_lib_rcv(skb, &udp_table, IPPROTO_UDP);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2397
  }
7d06b2e05   Brian Haley   net: change proto...
2398
  void udp_destroy_sock(struct sock *sk)
db8dac20d   David S. Miller   [UDP]: Revert udp...
2399
  {
44046a593   Tom Parkin   udp: add encap_de...
2400
  	struct udp_sock *up = udp_sk(sk);
8a74ad60a   Eric Dumazet   net: fix lock_soc...
2401
  	bool slow = lock_sock_fast(sk);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2402
  	udp_flush_pending_frames(sk);
8a74ad60a   Eric Dumazet   net: fix lock_soc...
2403
  	unlock_sock_fast(sk, slow);
60fb9567b   Paolo Abeni   udp: implement co...
2404
2405
2406
2407
2408
2409
2410
2411
  	if (static_branch_unlikely(&udp_encap_needed_key)) {
  		if (up->encap_type) {
  			void (*encap_destroy)(struct sock *sk);
  			encap_destroy = READ_ONCE(up->encap_destroy);
  			if (encap_destroy)
  				encap_destroy(sk);
  		}
  		if (up->encap_enabled)
9c4806014   Paolo Abeni   udp: fix jump lab...
2412
  			static_branch_dec(&udp_encap_needed_key);
44046a593   Tom Parkin   udp: add encap_de...
2413
  	}
db8dac20d   David S. Miller   [UDP]: Revert udp...
2414
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2415
2416
2417
  /*
   *	Socket option code for UDP
   */
4c0a6cb0d   Gerrit Renker   [UDP(-Lite)]: con...
2418
  int udp_lib_setsockopt(struct sock *sk, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
2419
  		       char __user *optval, unsigned int optlen,
4c0a6cb0d   Gerrit Renker   [UDP(-Lite)]: con...
2420
  		       int (*push_pending_frames)(struct sock *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2421
2422
  {
  	struct udp_sock *up = udp_sk(sk);
1c19448c9   Tom Herbert   net: Make enablin...
2423
  	int val, valbool;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2424
  	int err = 0;
b2bf1e265   Wang Chen   [UDP]: Clean up f...
2425
  	int is_udplite = IS_UDPLITE(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2426

c482c5685   Eric Dumazet   udp: cleanups
2427
  	if (optlen < sizeof(int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2428
2429
2430
2431
  		return -EINVAL;
  
  	if (get_user(val, (int __user *)optval))
  		return -EFAULT;
1c19448c9   Tom Herbert   net: Make enablin...
2432
  	valbool = val ? 1 : 0;
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2433
  	switch (optname) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2434
2435
2436
2437
2438
2439
  	case UDP_CORK:
  		if (val != 0) {
  			up->corkflag = 1;
  		} else {
  			up->corkflag = 0;
  			lock_sock(sk);
4243cdc2c   Joe Perches   udp: Neaten funct...
2440
  			push_pending_frames(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2441
2442
2443
  			release_sock(sk);
  		}
  		break;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2444

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2445
2446
2447
2448
2449
  	case UDP_ENCAP:
  		switch (val) {
  		case 0:
  		case UDP_ENCAP_ESPINUDP:
  		case UDP_ENCAP_ESPINUDP_NON_IKE:
067b207b2   James Chapman   [UDP]: Cleanup UD...
2450
2451
  			up->encap_rcv = xfrm4_udp_encap_rcv;
  			/* FALLTHROUGH */
342f0234c   James Chapman   [UDP]: Introduce ...
2452
  		case UDP_ENCAP_L2TPINUDP:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2453
  			up->encap_type = val;
60fb9567b   Paolo Abeni   udp: implement co...
2454
2455
2456
  			lock_sock(sk);
  			udp_tunnel_encap_enable(sk->sk_socket);
  			release_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2457
2458
2459
2460
2461
2462
  			break;
  		default:
  			err = -ENOPROTOOPT;
  			break;
  		}
  		break;
1c19448c9   Tom Herbert   net: Make enablin...
2463
2464
2465
2466
2467
2468
2469
  	case UDP_NO_CHECK6_TX:
  		up->no_check6_tx = valbool;
  		break;
  
  	case UDP_NO_CHECK6_RX:
  		up->no_check6_rx = valbool;
  		break;
bec1f6f69   Willem de Bruijn   udp: generate gso...
2470
2471
2472
2473
2474
  	case UDP_SEGMENT:
  		if (val < 0 || val > USHRT_MAX)
  			return -EINVAL;
  		up->gso_size = val;
  		break;
e20cf8d3f   Paolo Abeni   udp: implement GR...
2475
2476
2477
2478
2479
2480
2481
  	case UDP_GRO:
  		lock_sock(sk);
  		if (valbool)
  			udp_tunnel_encap_enable(sk->sk_socket);
  		up->gro_enabled = valbool;
  		release_sock(sk);
  		break;
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2482
2483
2484
2485
2486
2487
  	/*
  	 * 	UDP-Lite's partial checksum coverage (RFC 3828).
  	 */
  	/* The sender sets actual checksum coverage length via this option.
  	 * The case coverage > packet length is handled by send module. */
  	case UDPLITE_SEND_CSCOV:
b2bf1e265   Wang Chen   [UDP]: Clean up f...
2488
  		if (!is_udplite)         /* Disable the option on UDP sockets */
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2489
2490
2491
  			return -ENOPROTOOPT;
  		if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
  			val = 8;
4be929be3   Alexey Dobriyan   kernel-wide: repl...
2492
2493
  		else if (val > USHRT_MAX)
  			val = USHRT_MAX;
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2494
2495
2496
  		up->pcslen = val;
  		up->pcflag |= UDPLITE_SEND_CC;
  		break;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2497
2498
  	/* The receiver specifies a minimum checksum coverage value. To make
  	 * sense, this should be set to at least 8 (as done below). If zero is
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2499
2500
  	 * used, this again means full checksum coverage.                     */
  	case UDPLITE_RECV_CSCOV:
b2bf1e265   Wang Chen   [UDP]: Clean up f...
2501
  		if (!is_udplite)         /* Disable the option on UDP sockets */
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2502
2503
2504
  			return -ENOPROTOOPT;
  		if (val != 0 && val < 8) /* Avoid silly minimal values.       */
  			val = 8;
4be929be3   Alexey Dobriyan   kernel-wide: repl...
2505
2506
  		else if (val > USHRT_MAX)
  			val = USHRT_MAX;
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2507
2508
2509
  		up->pcrlen = val;
  		up->pcflag |= UDPLITE_RECV_CC;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2510
2511
2512
  	default:
  		err = -ENOPROTOOPT;
  		break;
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2513
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2514
2515
2516
  
  	return err;
  }
c482c5685   Eric Dumazet   udp: cleanups
2517
  EXPORT_SYMBOL(udp_lib_setsockopt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2518

db8dac20d   David S. Miller   [UDP]: Revert udp...
2519
  int udp_setsockopt(struct sock *sk, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
2520
  		   char __user *optval, unsigned int optlen)
db8dac20d   David S. Miller   [UDP]: Revert udp...
2521
2522
2523
2524
2525
2526
2527
2528
2529
  {
  	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
  		return udp_lib_setsockopt(sk, level, optname, optval, optlen,
  					  udp_push_pending_frames);
  	return ip_setsockopt(sk, level, optname, optval, optlen);
  }
  
  #ifdef CONFIG_COMPAT
  int compat_udp_setsockopt(struct sock *sk, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
2530
  			  char __user *optval, unsigned int optlen)
db8dac20d   David S. Miller   [UDP]: Revert udp...
2531
2532
2533
2534
2535
2536
2537
  {
  	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
  		return udp_lib_setsockopt(sk, level, optname, optval, optlen,
  					  udp_push_pending_frames);
  	return compat_ip_setsockopt(sk, level, optname, optval, optlen);
  }
  #endif
4c0a6cb0d   Gerrit Renker   [UDP(-Lite)]: con...
2538
2539
  int udp_lib_getsockopt(struct sock *sk, int level, int optname,
  		       char __user *optval, int __user *optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2540
2541
2542
  {
  	struct udp_sock *up = udp_sk(sk);
  	int val, len;
c482c5685   Eric Dumazet   udp: cleanups
2543
  	if (get_user(len, optlen))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2544
2545
2546
  		return -EFAULT;
  
  	len = min_t(unsigned int, len, sizeof(int));
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2547

6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2548
  	if (len < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2549
  		return -EINVAL;
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2550
  	switch (optname) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2551
2552
2553
2554
2555
2556
2557
  	case UDP_CORK:
  		val = up->corkflag;
  		break;
  
  	case UDP_ENCAP:
  		val = up->encap_type;
  		break;
1c19448c9   Tom Herbert   net: Make enablin...
2558
2559
2560
2561
2562
2563
2564
  	case UDP_NO_CHECK6_TX:
  		val = up->no_check6_tx;
  		break;
  
  	case UDP_NO_CHECK6_RX:
  		val = up->no_check6_rx;
  		break;
bec1f6f69   Willem de Bruijn   udp: generate gso...
2565
2566
2567
  	case UDP_SEGMENT:
  		val = up->gso_size;
  		break;
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2568
2569
2570
2571
2572
2573
2574
2575
2576
  	/* The following two cannot be changed on UDP sockets, the return is
  	 * always 0 (which corresponds to the full checksum coverage of UDP). */
  	case UDPLITE_SEND_CSCOV:
  		val = up->pcslen;
  		break;
  
  	case UDPLITE_RECV_CSCOV:
  		val = up->pcrlen;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2577
2578
  	default:
  		return -ENOPROTOOPT;
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2579
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2580

6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2581
  	if (put_user(len, optlen))
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2582
  		return -EFAULT;
c482c5685   Eric Dumazet   udp: cleanups
2583
  	if (copy_to_user(optval, &val, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2584
  		return -EFAULT;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2585
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2586
  }
c482c5685   Eric Dumazet   udp: cleanups
2587
  EXPORT_SYMBOL(udp_lib_getsockopt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2588

db8dac20d   David S. Miller   [UDP]: Revert udp...
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
  int udp_getsockopt(struct sock *sk, int level, int optname,
  		   char __user *optval, int __user *optlen)
  {
  	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
  		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
  	return ip_getsockopt(sk, level, optname, optval, optlen);
  }
  
  #ifdef CONFIG_COMPAT
  int compat_udp_getsockopt(struct sock *sk, int level, int optname,
  				 char __user *optval, int __user *optlen)
  {
  	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
  		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
  	return compat_ip_getsockopt(sk, level, optname, optval, optlen);
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2606
2607
2608
2609
  /**
   * 	udp_poll - wait for a UDP event.
   *	@file - file struct
   *	@sock - socket
a11e1d432   Linus Torvalds   Revert changes to...
2610
   *	@wait - poll table
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2611
   *
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2612
   *	This is same as datagram poll, except for the special case of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2613
2614
2615
2616
2617
2618
   *	blocking sockets. If application is using a blocking fd
   *	and a packet with checksum error is in the queue;
   *	then it could get return from select indicating data available
   *	but then block when reading it. Add special case code
   *	to work around these arguably broken applications.
   */
a11e1d432   Linus Torvalds   Revert changes to...
2619
  __poll_t udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2620
  {
a11e1d432   Linus Torvalds   Revert changes to...
2621
  	__poll_t mask = datagram_poll(file, sock, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2622
  	struct sock *sk = sock->sk;
ba4e58eca   Gerrit Renker   [NET]: Supporting...
2623

3ef7cf57c   Eric Dumazet   net: use skb_queu...
2624
  	if (!skb_queue_empty_lockless(&udp_sk(sk)->reader_queue))
a9a08845e   Linus Torvalds   vfs: do bulk POLL...
2625
  		mask |= EPOLLIN | EPOLLRDNORM;
2276f58ac   Paolo Abeni   udp: use a separa...
2626

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2627
  	/* Check for false positives due to checksum errors */
a11e1d432   Linus Torvalds   Revert changes to...
2628
  	if ((mask & EPOLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
e83c6744e   Eric Dumazet   udp: fix poll() i...
2629
  	    !(sk->sk_shutdown & RCV_SHUTDOWN) && first_packet_length(sk) == -1)
a9a08845e   Linus Torvalds   vfs: do bulk POLL...
2630
  		mask &= ~(EPOLLIN | EPOLLRDNORM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2631
2632
  
  	return mask;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
2633

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2634
  }
a11e1d432   Linus Torvalds   Revert changes to...
2635
  EXPORT_SYMBOL(udp_poll);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2636

5d77dca82   David Ahern   net: diag: suppor...
2637
2638
2639
2640
2641
2642
  int udp_abort(struct sock *sk, int err)
  {
  	lock_sock(sk);
  
  	sk->sk_err = err;
  	sk->sk_error_report(sk);
286c72dea   Eric Dumazet   udp: must lock th...
2643
  	__udp_disconnect(sk, 0);
5d77dca82   David Ahern   net: diag: suppor...
2644
2645
2646
2647
2648
2649
  
  	release_sock(sk);
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(udp_abort);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2650
  struct proto udp_prot = {
1e8029515   Tonghao Zhang   udp: Move the udp...
2651
2652
2653
  	.name			= "UDP",
  	.owner			= THIS_MODULE,
  	.close			= udp_lib_close,
d74bad4e7   Andrey Ignatov   bpf: Hooks for sy...
2654
  	.pre_connect		= udp_pre_connect,
1e8029515   Tonghao Zhang   udp: Move the udp...
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
  	.connect		= ip4_datagram_connect,
  	.disconnect		= udp_disconnect,
  	.ioctl			= udp_ioctl,
  	.init			= udp_init_sock,
  	.destroy		= udp_destroy_sock,
  	.setsockopt		= udp_setsockopt,
  	.getsockopt		= udp_getsockopt,
  	.sendmsg		= udp_sendmsg,
  	.recvmsg		= udp_recvmsg,
  	.sendpage		= udp_sendpage,
  	.release_cb		= ip4_datagram_release_cb,
  	.hash			= udp_lib_hash,
  	.unhash			= udp_lib_unhash,
  	.rehash			= udp_v4_rehash,
  	.get_port		= udp_v4_get_port,
  	.memory_allocated	= &udp_memory_allocated,
  	.sysctl_mem		= sysctl_udp_mem,
  	.sysctl_wmem_offset	= offsetof(struct net, ipv4.sysctl_udp_wmem_min),
  	.sysctl_rmem_offset	= offsetof(struct net, ipv4.sysctl_udp_rmem_min),
  	.obj_size		= sizeof(struct udp_sock),
  	.h.udp_table		= &udp_table,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2676
  #ifdef CONFIG_COMPAT
1e8029515   Tonghao Zhang   udp: Move the udp...
2677
2678
  	.compat_setsockopt	= compat_udp_setsockopt,
  	.compat_getsockopt	= compat_udp_getsockopt,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2679
  #endif
1e8029515   Tonghao Zhang   udp: Move the udp...
2680
  	.diag_destroy		= udp_abort,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2681
  };
c482c5685   Eric Dumazet   udp: cleanups
2682
  EXPORT_SYMBOL(udp_prot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2683
2684
2685
  
  /* ------------------------------------------------------------------------ */
  #ifdef CONFIG_PROC_FS
645ca708f   Eric Dumazet   udp: introduce st...
2686
  static struct sock *udp_get_first(struct seq_file *seq, int start)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2687
2688
  {
  	struct sock *sk;
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2689
  	struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2690
  	struct udp_iter_state *state = seq->private;
6f191efe4   Denis V. Lunev   [UDP]: Replace st...
2691
  	struct net *net = seq_file_net(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2692

a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2693
  	for (state->bucket = start; state->bucket <= afinfo->udp_table->mask;
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2694
  	     ++state->bucket) {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2695
  		struct udp_hslot *hslot = &afinfo->udp_table->hash[state->bucket];
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2696

ca065d0cf   Eric Dumazet   udp: no longer us...
2697
  		if (hlist_empty(&hslot->head))
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2698
  			continue;
645ca708f   Eric Dumazet   udp: introduce st...
2699
  		spin_lock_bh(&hslot->lock);
ca065d0cf   Eric Dumazet   udp: no longer us...
2700
  		sk_for_each(sk, &hslot->head) {
878628fbf   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
2701
  			if (!net_eq(sock_net(sk), net))
a91275eff   Daniel Lezcano   [NETNS][IPV6] udp...
2702
  				continue;
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2703
  			if (sk->sk_family == afinfo->family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2704
2705
  				goto found;
  		}
645ca708f   Eric Dumazet   udp: introduce st...
2706
  		spin_unlock_bh(&hslot->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2707
2708
2709
2710
2711
2712
2713
2714
  	}
  	sk = NULL;
  found:
  	return sk;
  }
  
  static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
  {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2715
  	struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2716
  	struct udp_iter_state *state = seq->private;
6f191efe4   Denis V. Lunev   [UDP]: Replace st...
2717
  	struct net *net = seq_file_net(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2718
2719
  
  	do {
ca065d0cf   Eric Dumazet   udp: no longer us...
2720
  		sk = sk_next(sk);
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2721
  	} while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != afinfo->family));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2722

645ca708f   Eric Dumazet   udp: introduce st...
2723
  	if (!sk) {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2724
2725
  		if (state->bucket <= afinfo->udp_table->mask)
  			spin_unlock_bh(&afinfo->udp_table->hash[state->bucket].lock);
645ca708f   Eric Dumazet   udp: introduce st...
2726
  		return udp_get_first(seq, state->bucket + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2727
2728
2729
2730
2731
2732
  	}
  	return sk;
  }
  
  static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
  {
645ca708f   Eric Dumazet   udp: introduce st...
2733
  	struct sock *sk = udp_get_first(seq, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2734
2735
  
  	if (sk)
6516c6557   Stephen Hemminger   [UDP]: ipv4 white...
2736
  		while (pos && (sk = udp_get_next(seq, sk)) != NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2737
2738
2739
  			--pos;
  	return pos ? NULL : sk;
  }
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2740
  void *udp_seq_start(struct seq_file *seq, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2741
  {
30842f298   Vitaly Mayatskikh   udp: Wrong lockin...
2742
  	struct udp_iter_state *state = seq->private;
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2743
  	state->bucket = MAX_UDP_PORTS;
30842f298   Vitaly Mayatskikh   udp: Wrong lockin...
2744

b50660f1f   YOSHIFUJI Hideaki   [IP] UDP: Use SEQ...
2745
  	return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2746
  }
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2747
  EXPORT_SYMBOL(udp_seq_start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2748

a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2749
  void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2750
2751
  {
  	struct sock *sk;
b50660f1f   YOSHIFUJI Hideaki   [IP] UDP: Use SEQ...
2752
  	if (v == SEQ_START_TOKEN)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2753
2754
2755
2756
2757
2758
2759
  		sk = udp_get_idx(seq, 0);
  	else
  		sk = udp_get_next(seq, v);
  
  	++*pos;
  	return sk;
  }
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2760
  EXPORT_SYMBOL(udp_seq_next);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2761

a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2762
  void udp_seq_stop(struct seq_file *seq, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2763
  {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2764
  	struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
645ca708f   Eric Dumazet   udp: introduce st...
2765
  	struct udp_iter_state *state = seq->private;
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2766
2767
  	if (state->bucket <= afinfo->udp_table->mask)
  		spin_unlock_bh(&afinfo->udp_table->hash[state->bucket].lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2768
  }
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2769
  EXPORT_SYMBOL(udp_seq_stop);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2770
2771
  
  /* ------------------------------------------------------------------------ */
5e659e4cb   Pavel Emelyanov   [NET]: Fix heavy ...
2772
  static void udp4_format_sock(struct sock *sp, struct seq_file *f,
652586df9   Tetsuo Handa   seq_file: remove ...
2773
  		int bucket)
db8dac20d   David S. Miller   [UDP]: Revert udp...
2774
2775
  {
  	struct inet_sock *inet = inet_sk(sp);
c720c7e83   Eric Dumazet   inet: rename some...
2776
2777
2778
2779
  	__be32 dest = inet->inet_daddr;
  	__be32 src  = inet->inet_rcv_saddr;
  	__u16 destp	  = ntohs(inet->inet_dport);
  	__u16 srcp	  = ntohs(inet->inet_sport);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2780

f86dcc5aa   Eric Dumazet   udp: dynamically ...
2781
  	seq_printf(f, "%5d: %08X:%04X %08X:%04X"
ea9a03791   Patrick Talbert   net: Treat sock->...
2782
  		" %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u",
db8dac20d   David S. Miller   [UDP]: Revert udp...
2783
  		bucket, src, srcp, dest, destp, sp->sk_state,
31e6d363a   Eric Dumazet   net: correct off-...
2784
  		sk_wmem_alloc_get(sp),
6c206b200   Paolo Abeni   udp: fix rx queue...
2785
  		udp_rqueue_get(sp),
a7cb5a49b   Eric W. Biederman   userns: Print out...
2786
2787
2788
  		0, 0L, 0,
  		from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
  		0, sock_i_ino(sp),
41c6d650f   Reshetova, Elena   net: convert sock...
2789
  		refcount_read(&sp->sk_refcnt), sp,
652586df9   Tetsuo Handa   seq_file: remove ...
2790
  		atomic_read(&sp->sk_drops));
db8dac20d   David S. Miller   [UDP]: Revert udp...
2791
2792
2793
2794
  }
  
  int udp4_seq_show(struct seq_file *seq, void *v)
  {
652586df9   Tetsuo Handa   seq_file: remove ...
2795
  	seq_setwidth(seq, 127);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2796
  	if (v == SEQ_START_TOKEN)
652586df9   Tetsuo Handa   seq_file: remove ...
2797
  		seq_puts(seq, "  sl  local_address rem_address   st tx_queue "
db8dac20d   David S. Miller   [UDP]: Revert udp...
2798
  			   "rx_queue tr tm->when retrnsmt   uid  timeout "
cb61cb9b8   Eric Dumazet   udp: sk_drops han...
2799
  			   "inode ref pointer drops");
db8dac20d   David S. Miller   [UDP]: Revert udp...
2800
  	else {
db8dac20d   David S. Miller   [UDP]: Revert udp...
2801
  		struct udp_iter_state *state = seq->private;
652586df9   Tetsuo Handa   seq_file: remove ...
2802
  		udp4_format_sock(v, seq, state->bucket);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2803
  	}
652586df9   Tetsuo Handa   seq_file: remove ...
2804
2805
  	seq_pad(seq, '
  ');
db8dac20d   David S. Miller   [UDP]: Revert udp...
2806
2807
  	return 0;
  }
c35063722   Christoph Hellwig   proc: introduce p...
2808
  const struct seq_operations udp_seq_ops = {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2809
2810
2811
2812
2813
  	.start		= udp_seq_start,
  	.next		= udp_seq_next,
  	.stop		= udp_seq_stop,
  	.show		= udp4_seq_show,
  };
c35063722   Christoph Hellwig   proc: introduce p...
2814
  EXPORT_SYMBOL(udp_seq_ops);
73cb88ecb   Arjan van de Ven   net: make the tcp...
2815

db8dac20d   David S. Miller   [UDP]: Revert udp...
2816
  static struct udp_seq_afinfo udp4_seq_afinfo = {
db8dac20d   David S. Miller   [UDP]: Revert udp...
2817
  	.family		= AF_INET,
645ca708f   Eric Dumazet   udp: introduce st...
2818
  	.udp_table	= &udp_table,
db8dac20d   David S. Miller   [UDP]: Revert udp...
2819
  };
2c8c1e729   Alexey Dobriyan   net: spread __net...
2820
  static int __net_init udp4_proc_init_net(struct net *net)
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2821
  {
c35063722   Christoph Hellwig   proc: introduce p...
2822
2823
  	if (!proc_create_net_data("udp", 0444, net->proc_net, &udp_seq_ops,
  			sizeof(struct udp_iter_state), &udp4_seq_afinfo))
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2824
2825
  		return -ENOMEM;
  	return 0;
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2826
  }
2c8c1e729   Alexey Dobriyan   net: spread __net...
2827
  static void __net_exit udp4_proc_exit_net(struct net *net)
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2828
  {
a3d2599b2   Christoph Hellwig   ipv{4,6}/udp{,lit...
2829
  	remove_proc_entry("udp", net->proc_net);
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2830
2831
2832
2833
2834
2835
  }
  
  static struct pernet_operations udp4_net_ops = {
  	.init = udp4_proc_init_net,
  	.exit = udp4_proc_exit_net,
  };
db8dac20d   David S. Miller   [UDP]: Revert udp...
2836
2837
  int __init udp4_proc_init(void)
  {
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2838
  	return register_pernet_subsys(&udp4_net_ops);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2839
2840
2841
2842
  }
  
  void udp4_proc_exit(void)
  {
15439febb   Pavel Emelyanov   [NETNS][UDP]: Reg...
2843
  	unregister_pernet_subsys(&udp4_net_ops);
db8dac20d   David S. Miller   [UDP]: Revert udp...
2844
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2845
  #endif /* CONFIG_PROC_FS */
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2846
2847
  static __initdata unsigned long uhash_entries;
  static int __init set_uhash_entries(char *str)
645ca708f   Eric Dumazet   udp: introduce st...
2848
  {
413c27d86   Eldad Zack   net/ipv4: replace...
2849
  	ssize_t ret;
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2850
2851
  	if (!str)
  		return 0;
413c27d86   Eldad Zack   net/ipv4: replace...
2852
2853
2854
2855
  
  	ret = kstrtoul(str, 0, &uhash_entries);
  	if (ret)
  		return 0;
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2856
2857
2858
2859
2860
  	if (uhash_entries && uhash_entries < UDP_HTABLE_SIZE_MIN)
  		uhash_entries = UDP_HTABLE_SIZE_MIN;
  	return 1;
  }
  __setup("uhash_entries=", set_uhash_entries);
645ca708f   Eric Dumazet   udp: introduce st...
2861

f86dcc5aa   Eric Dumazet   udp: dynamically ...
2862
2863
2864
  void __init udp_table_init(struct udp_table *table, const char *name)
  {
  	unsigned int i;
31fe62b95   Tim Bird   mm: add a low lim...
2865
2866
2867
2868
2869
2870
2871
2872
2873
  	table->hash = alloc_large_system_hash(name,
  					      2 * sizeof(struct udp_hslot),
  					      uhash_entries,
  					      21, /* one slot per 2 MB */
  					      0,
  					      &table->log,
  					      &table->mask,
  					      UDP_HTABLE_SIZE_MIN,
  					      64 * 1024);
512615b6b   Eric Dumazet   udp: secondary ha...
2874
  	table->hash2 = table->hash + (table->mask + 1);
f86dcc5aa   Eric Dumazet   udp: dynamically ...
2875
  	for (i = 0; i <= table->mask; i++) {
ca065d0cf   Eric Dumazet   udp: no longer us...
2876
  		INIT_HLIST_HEAD(&table->hash[i].head);
fdcc8aa95   Eric Dumazet   udp: add a counte...
2877
  		table->hash[i].count = 0;
645ca708f   Eric Dumazet   udp: introduce st...
2878
2879
  		spin_lock_init(&table->hash[i].lock);
  	}
512615b6b   Eric Dumazet   udp: secondary ha...
2880
  	for (i = 0; i <= table->mask; i++) {
ca065d0cf   Eric Dumazet   udp: no longer us...
2881
  		INIT_HLIST_HEAD(&table->hash2[i].head);
512615b6b   Eric Dumazet   udp: secondary ha...
2882
2883
2884
  		table->hash2[i].count = 0;
  		spin_lock_init(&table->hash2[i].lock);
  	}
645ca708f   Eric Dumazet   udp: introduce st...
2885
  }
723b8e460   Tom Herbert   udp: In udp_flow_...
2886
2887
2888
2889
2890
2891
2892
2893
2894
  u32 udp_flow_hashrnd(void)
  {
  	static u32 hashrnd __read_mostly;
  
  	net_get_random_once(&hashrnd, sizeof(hashrnd));
  
  	return hashrnd;
  }
  EXPORT_SYMBOL(udp_flow_hashrnd);
1e8029515   Tonghao Zhang   udp: Move the udp...
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
  static void __udp_sysctl_init(struct net *net)
  {
  	net->ipv4.sysctl_udp_rmem_min = SK_MEM_QUANTUM;
  	net->ipv4.sysctl_udp_wmem_min = SK_MEM_QUANTUM;
  
  #ifdef CONFIG_NET_L3_MASTER_DEV
  	net->ipv4.sysctl_udp_l3mdev_accept = 0;
  #endif
  }
  
  static int __net_init udp_sysctl_init(struct net *net)
  {
  	__udp_sysctl_init(net);
  	return 0;
  }
  
  static struct pernet_operations __net_initdata udp_sysctl_ops = {
fc18999ed   Kirill Tkhai   net: Convert udp_...
2912
  	.init	= udp_sysctl_init,
1e8029515   Tonghao Zhang   udp: Move the udp...
2913
  };
95766fff6   Hideo Aoki   [UDP]: Add memory...
2914
2915
  void __init udp_init(void)
  {
f03d78db6   Eric Dumazet   net: refine {udp|...
2916
  	unsigned long limit;
4b272750d   Eric Dumazet   udp: add busylock...
2917
  	unsigned int i;
95766fff6   Hideo Aoki   [UDP]: Add memory...
2918

f86dcc5aa   Eric Dumazet   udp: dynamically ...
2919
  	udp_table_init(&udp_table, "UDP");
f03d78db6   Eric Dumazet   net: refine {udp|...
2920
  	limit = nr_free_buffer_pages() / 8;
95766fff6   Hideo Aoki   [UDP]: Add memory...
2921
2922
2923
2924
  	limit = max(limit, 128UL);
  	sysctl_udp_mem[0] = limit / 4 * 3;
  	sysctl_udp_mem[1] = limit;
  	sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2;
1e8029515   Tonghao Zhang   udp: Move the udp...
2925
  	__udp_sysctl_init(&init_net);
4b272750d   Eric Dumazet   udp: add busylock...
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
  
  	/* 16 spinlocks per cpu */
  	udp_busylocks_log = ilog2(nr_cpu_ids) + 4;
  	udp_busylocks = kmalloc(sizeof(spinlock_t) << udp_busylocks_log,
  				GFP_KERNEL);
  	if (!udp_busylocks)
  		panic("UDP: failed to alloc udp_busylocks
  ");
  	for (i = 0; i < (1U << udp_busylocks_log); i++)
  		spin_lock_init(udp_busylocks + i);
1e8029515   Tonghao Zhang   udp: Move the udp...
2936
2937
2938
2939
  
  	if (register_pernet_subsys(&udp_sysctl_ops))
  		panic("UDP: failed to init sysctl parameters.
  ");
95766fff6   Hideo Aoki   [UDP]: Add memory...
2940
  }