Blame view

net/dccp/ipv4.c 28.6 KB
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
1
2
3
4
5
6
7
8
9
10
11
  /*
   *  net/dccp/ipv4.c
   *
   *  An implementation of the DCCP protocol
   *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
12
13
  #include <linux/dccp.h>
  #include <linux/icmp.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
14
  #include <linux/slab.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
15
16
17
18
19
  #include <linux/module.h>
  #include <linux/skbuff.h>
  #include <linux/random.h>
  
  #include <net/icmp.h>
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
20
  #include <net/inet_common.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
21
  #include <net/inet_hashtables.h>
14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
22
  #include <net/inet_sock.h>
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
23
  #include <net/protocol.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
24
  #include <net/sock.h>
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
25
  #include <net/timewait_sock.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
26
27
  #include <net/tcp_states.h>
  #include <net/xfrm.h>
6e5714eaf   David S. Miller   net: Compute prot...
28
  #include <net/secure_seq.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
29

ae31c3399   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
30
  #include "ackvec.h"
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
31
32
  #include "ccid.h"
  #include "dccp.h"
afe00251d   Andrea Bittau   [DCCP]: Initial f...
33
  #include "feat.h"
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
34

724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
35
  /*
13f51d82a   Pavel Emelyanov   [DCCP]: Fix comme...
36
   * The per-net dccp.v4_ctl_sk socket is used for responding to
724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
37
38
39
   * the Out-of-the-blue (OOTB) packets. A control sock will be created
   * for this socket at the initialization time.
   */
724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
40

f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
41
  int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
42
  {
2d7192d6c   David S. Miller   ipv4: Sanitize an...
43
  	const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
44
45
  	struct inet_sock *inet = inet_sk(sk);
  	struct dccp_sock *dp = dccp_sk(sk);
dca8b089c   David S. Miller   ipv4: Rearrange h...
46
  	__be16 orig_sport, orig_dport;
bada8adc4   Al Viro   [IPV4]: ip_route_...
47
  	__be32 daddr, nexthop;
2c42758cf   David S. Miller   dccp: Use cork fl...
48
  	struct flowi4 *fl4;
2d7192d6c   David S. Miller   ipv4: Sanitize an...
49
  	struct rtable *rt;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
50
  	int err;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
51
  	struct ip_options_rcu *inet_opt;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
52
53
54
55
56
57
58
59
60
61
  
  	dp->dccps_role = DCCP_ROLE_CLIENT;
  
  	if (addr_len < sizeof(struct sockaddr_in))
  		return -EINVAL;
  
  	if (usin->sin_family != AF_INET)
  		return -EAFNOSUPPORT;
  
  	nexthop = daddr = usin->sin_addr.s_addr;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
62
63
  
  	inet_opt = rcu_dereference_protected(inet->inet_opt,
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
64
  					     lockdep_sock_is_held(sk));
f6d8bd051   Eric Dumazet   inet: add RCU pro...
65
  	if (inet_opt != NULL && inet_opt->opt.srr) {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
66
67
  		if (daddr == 0)
  			return -EINVAL;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
68
  		nexthop = inet_opt->opt.faddr;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
69
  	}
dca8b089c   David S. Miller   ipv4: Rearrange h...
70
71
  	orig_sport = inet->inet_sport;
  	orig_dport = usin->sin_port;
2c42758cf   David S. Miller   dccp: Use cork fl...
72
73
  	fl4 = &inet->cork.fl.u.ip4;
  	rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
b23dd4fe4   David S. Miller   ipv4: Make output...
74
75
  			      RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
  			      IPPROTO_DCCP,
0e0d44ab4   Steffen Klassert   net: Remove FLOWI...
76
  			      orig_sport, orig_dport, sk);
b23dd4fe4   David S. Miller   ipv4: Make output...
77
78
  	if (IS_ERR(rt))
  		return PTR_ERR(rt);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
79
80
81
82
83
  
  	if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
  		ip_rt_put(rt);
  		return -ENETUNREACH;
  	}
f6d8bd051   Eric Dumazet   inet: add RCU pro...
84
  	if (inet_opt == NULL || !inet_opt->opt.srr)
2c42758cf   David S. Miller   dccp: Use cork fl...
85
  		daddr = fl4->daddr;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
86

c720c7e83   Eric Dumazet   inet: rename some...
87
  	if (inet->inet_saddr == 0)
2c42758cf   David S. Miller   dccp: Use cork fl...
88
  		inet->inet_saddr = fl4->saddr;
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
89
  	sk_rcv_saddr_set(sk, inet->inet_saddr);
c720c7e83   Eric Dumazet   inet: rename some...
90
  	inet->inet_dport = usin->sin_port;
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
91
  	sk_daddr_set(sk, daddr);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
92

d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
93
  	inet_csk(sk)->icsk_ext_hdr_len = 0;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
94
95
  	if (inet_opt)
  		inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
96
97
98
99
100
101
102
  	/*
  	 * Socket identity is still unknown (sport may be zero).
  	 * However we set state to DCCP_REQUESTING and not releasing socket
  	 * lock select source port, enter ourselves into the hash tables and
  	 * complete initialization after this.
  	 */
  	dccp_set_state(sk, DCCP_REQUESTING);
a7f5e7f16   Arnaldo Carvalho de Melo   [INET]: Generalis...
103
  	err = inet_hash_connect(&dccp_death_row, sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
104
105
  	if (err != 0)
  		goto failure;
2c42758cf   David S. Miller   dccp: Use cork fl...
106
  	rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
b23dd4fe4   David S. Miller   ipv4: Make output...
107
108
  			       inet->inet_sport, inet->inet_dport, sk);
  	if (IS_ERR(rt)) {
525c6465d   RongQing.Li   dccp: fix error p...
109
  		err = PTR_ERR(rt);
b23dd4fe4   David S. Miller   ipv4: Make output...
110
  		rt = NULL;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
111
  		goto failure;
b23dd4fe4   David S. Miller   ipv4: Make output...
112
  	}
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
113
  	/* OK, now commit destination to socket.  */
d8d1f30b9   Changli Gao   net-next: remove ...
114
  	sk_setup_caps(sk, &rt->dst);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
115

c720c7e83   Eric Dumazet   inet: rename some...
116
117
118
119
120
  	dp->dccps_iss = secure_dccp_sequence_number(inet->inet_saddr,
  						    inet->inet_daddr,
  						    inet->inet_sport,
  						    inet->inet_dport);
  	inet->inet_id = dp->dccps_iss ^ jiffies;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
121
122
123
124
125
126
127
128
  
  	err = dccp_connect(sk);
  	rt = NULL;
  	if (err != 0)
  		goto failure;
  out:
  	return err;
  failure:
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
129
130
131
  	/*
  	 * This unhashes the socket and releases the local port, if necessary.
  	 */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
132
133
134
  	dccp_set_state(sk, DCCP_CLOSED);
  	ip_rt_put(rt);
  	sk->sk_route_caps = 0;
c720c7e83   Eric Dumazet   inet: rename some...
135
  	inet->inet_dport = 0;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
136
137
  	goto out;
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
138
  EXPORT_SYMBOL_GPL(dccp_v4_connect);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  /*
   * This routine does path mtu discovery as defined in RFC1191.
   */
  static inline void dccp_do_pmtu_discovery(struct sock *sk,
  					  const struct iphdr *iph,
  					  u32 mtu)
  {
  	struct dst_entry *dst;
  	const struct inet_sock *inet = inet_sk(sk);
  	const struct dccp_sock *dp = dccp_sk(sk);
  
  	/* We are not interested in DCCP_LISTEN and request_socks (RESPONSEs
  	 * send out by Linux are always < 576bytes so they should go through
  	 * unfragmented).
  	 */
  	if (sk->sk_state == DCCP_LISTEN)
  		return;
80d0a69fc   David S. Miller   ipv4: Add helper ...
156
157
  	dst = inet_csk_update_pmtu(sk, mtu);
  	if (!dst)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
158
  		return;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
159
160
161
162
163
164
165
166
167
  	/* Something is about to be wrong... Remember soft error
  	 * for the case, if this connection will not able to recover.
  	 */
  	if (mtu < dst_mtu(dst) && ip_dont_fragment(sk, dst))
  		sk->sk_err_soft = EMSGSIZE;
  
  	mtu = dst_mtu(dst);
  
  	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
482fc6094   Hannes Frederic Sowa   ipv4: introduce n...
168
  	    ip_sk_accept_pmtu(sk) &&
d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
169
  	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
170
171
172
  		dccp_sync_mss(sk, mtu);
  
  		/*
0e64e94e4   Gerrit Renker   [DCCP]: Update do...
173
  		 * From RFC 4340, sec. 14.1:
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
174
  		 *
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
175
176
177
  		 *	DCCP-Sync packets are the best choice for upward
  		 *	probing, since DCCP-Sync probes do not risk application
  		 *	data loss.
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
178
  		 */
e92ae93a8   Arnaldo Carvalho de Melo   [DCCP]: Send SYNC...
179
  		dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
180
181
  	} /* else let the usual retransmit timer handle it */
  }
55be7a9c6   David S. Miller   ipv4: Add redirec...
182
183
184
  static void dccp_do_redirect(struct sk_buff *skb, struct sock *sk)
  {
  	struct dst_entry *dst = __sk_dst_check(sk, 0);
1ed5c48f2   David S. Miller   net: Remove check...
185
  	if (dst)
6700c2709   David S. Miller   net: Pass optiona...
186
  		dst->ops->redirect(dst, sk, skb);
55be7a9c6   David S. Miller   ipv4: Add redirec...
187
  }
85645bab5   Eric Dumazet   ipv4: dccp: handl...
188
189
190
191
192
193
194
195
196
  void dccp_req_err(struct sock *sk, u64 seq)
  	{
  	struct request_sock *req = inet_reqsk(sk);
  	struct net *net = sock_net(sk);
  
  	/*
  	 * ICMPs are not backlogged, hence we cannot get an established
  	 * socket here.
  	 */
85645bab5   Eric Dumazet   ipv4: dccp: handl...
197
  	if (!between48(seq, dccp_rsk(req)->dreq_iss, dccp_rsk(req)->dreq_gss)) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
198
  		__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
85645bab5   Eric Dumazet   ipv4: dccp: handl...
199
200
201
202
203
204
205
206
207
  	} else {
  		/*
  		 * Still in RESPOND, just remove it silently.
  		 * There is no good way to pass the error to the newly
  		 * created socket, and POSIX does not want network
  		 * errors returned from accept().
  		 */
  		inet_csk_reqsk_queue_drop(req->rsk_listener, req);
  	}
ef84d8ce5   Eric Dumazet   Revert "inet: fix...
208
  	reqsk_put(req);
85645bab5   Eric Dumazet   ipv4: dccp: handl...
209
210
  }
  EXPORT_SYMBOL(dccp_req_err);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
211
212
213
214
215
216
217
218
219
220
221
222
  /*
   * 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.
   * After adjustment header points to the first 8 bytes of the tcp header. We
   * need to find the appropriate port.
   *
   * The locking strategy used here is very "optimistic". When someone else
   * accesses the socket the ICMP is just dropped and for some paths there is no
   * check at all. A more general error queue to queue errors for later handling
   * is probably better.
   */
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
223
  static void dccp_v4_err(struct sk_buff *skb, u32 info)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
224
225
  {
  	const struct iphdr *iph = (struct iphdr *)skb->data;
18e1d8360   Wei Yongjun   dccp: Fix incorre...
226
  	const u8 offset = iph->ihl << 2;
6706a97fe   Eric Dumazet   dccp: fix out of ...
227
  	const struct dccp_hdr *dh;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
228
229
  	struct dccp_sock *dp;
  	struct inet_sock *inet;
88c7664f1   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
230
231
  	const int type = icmp_hdr(skb)->type;
  	const int code = icmp_hdr(skb)->code;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
232
233
234
  	struct sock *sk;
  	__u64 seq;
  	int err;
fd54d716b   Pavel Emelyanov   inet: toss struct...
235
  	struct net *net = dev_net(skb->dev);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
236

6706a97fe   Eric Dumazet   dccp: fix out of ...
237
238
239
240
241
242
243
  	/* Only need dccph_dport & dccph_sport which are the first
  	 * 4 bytes in dccp header.
  	 * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us.
  	 */
  	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
  	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
  	dh = (struct dccp_hdr *)(skb->data + offset);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
244

85645bab5   Eric Dumazet   ipv4: dccp: handl...
245
246
247
  	sk = __inet_lookup_established(net, &dccp_hashinfo,
  				       iph->daddr, dh->dccph_dport,
  				       iph->saddr, ntohs(dh->dccph_sport),
3fa6f616a   David Ahern   net: ipv4: add se...
248
  				       inet_iif(skb), 0);
85645bab5   Eric Dumazet   ipv4: dccp: handl...
249
  	if (!sk) {
5d3848bc3   Eric Dumazet   net: rename ICMP_...
250
  		__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
251
252
253
254
  		return;
  	}
  
  	if (sk->sk_state == DCCP_TIME_WAIT) {
9469c7b4a   YOSHIFUJI Hideaki   [NET]: Use typesa...
255
  		inet_twsk_put(inet_twsk(sk));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
256
257
  		return;
  	}
85645bab5   Eric Dumazet   ipv4: dccp: handl...
258
259
260
  	seq = dccp_hdr_seq(dh);
  	if (sk->sk_state == DCCP_NEW_SYN_RECV)
  		return dccp_req_err(sk, seq);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
261
262
263
264
265
266
  
  	bh_lock_sock(sk);
  	/* If too many ICMPs get dropped on busy
  	 * servers this needs to be solved differently.
  	 */
  	if (sock_owned_by_user(sk))
02a1d6e7a   Eric Dumazet   net: rename NET_{...
267
  		__NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
268
269
270
271
272
  
  	if (sk->sk_state == DCCP_CLOSED)
  		goto out;
  
  	dp = dccp_sk(sk);
1238d0873   Gerrit Renker   [DCCP]: One more ...
273
  	if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
d68f0866f   Wei Yongjun   dccp: Fix sequenc...
274
  	    !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
275
  		__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
276
277
278
279
  		goto out;
  	}
  
  	switch (type) {
55be7a9c6   David S. Miller   ipv4: Add redirec...
280
  	case ICMP_REDIRECT:
45caeaa5a   Jon Maxwell   dccp/tcp: fix rou...
281
282
  		if (!sock_owned_by_user(sk))
  			dccp_do_redirect(skb, sk);
55be7a9c6   David S. Miller   ipv4: Add redirec...
283
  		goto out;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  	case ICMP_SOURCE_QUENCH:
  		/* Just silently ignore these. */
  		goto out;
  	case ICMP_PARAMETERPROB:
  		err = EPROTO;
  		break;
  	case ICMP_DEST_UNREACH:
  		if (code > NR_ICMP_UNREACH)
  			goto out;
  
  		if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
  			if (!sock_owned_by_user(sk))
  				dccp_do_pmtu_discovery(sk, iph, info);
  			goto out;
  		}
  
  		err = icmp_err_convert[code].errno;
  		break;
  	case ICMP_TIME_EXCEEDED:
  		err = EHOSTUNREACH;
  		break;
  	default:
  		goto out;
  	}
  
  	switch (sk->sk_state) {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
310
311
312
  	case DCCP_REQUESTING:
  	case DCCP_RESPOND:
  		if (!sock_owned_by_user(sk)) {
aa62d76b6   Eric Dumazet   dccp: rename DCCP...
313
  			__DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  			sk->sk_err = err;
  
  			sk->sk_error_report(sk);
  
  			dccp_done(sk);
  		} else
  			sk->sk_err_soft = err;
  		goto out;
  	}
  
  	/* If we've already connected we will keep trying
  	 * until we time out, or the user gives up.
  	 *
  	 * rfc1122 4.2.3.9 allows to consider as hard errors
  	 * only PROTO_UNREACH and PORT_UNREACH (well, FRAG_FAILED too,
  	 * but it is obsoleted by pmtu discovery).
  	 *
  	 * Note, that in modern internet, where routing is unreliable
  	 * and in each dark corner broken firewalls sit, sending random
  	 * errors ordered by their masters even this two messages finally lose
  	 * their original sense (even Linux sends invalid PORT_UNREACHs)
  	 *
  	 * Now we are in compliance with RFCs.
  	 *							--ANK (980905)
  	 */
  
  	inet = inet_sk(sk);
  	if (!sock_owned_by_user(sk) && inet->recverr) {
  		sk->sk_err = err;
  		sk->sk_error_report(sk);
  	} else /* Only an error on timeout */
  		sk->sk_err_soft = err;
  out:
  	bh_unlock_sock(sk);
  	sock_put(sk);
  }
2bda28531   Al Viro   [NET]: Annotate c...
350
  static inline __sum16 dccp_v4_csum_finish(struct sk_buff *skb,
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
351
352
353
354
  				      __be32 src, __be32 dst)
  {
  	return csum_tcpudp_magic(src, dst, skb->len, IPPROTO_DCCP, skb->csum);
  }
bb2962461   Herbert Xu   inet: Remove unus...
355
  void dccp_v4_send_check(struct sock *sk, struct sk_buff *skb)
57cca05af   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
356
357
358
  {
  	const struct inet_sock *inet = inet_sk(sk);
  	struct dccp_hdr *dh = dccp_hdr(skb);
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
359
  	dccp_csum_outgoing(skb);
c720c7e83   Eric Dumazet   inet: rename some...
360
361
362
  	dh->dccph_checksum = dccp_v4_csum_finish(skb,
  						 inet->inet_saddr,
  						 inet->inet_daddr);
57cca05af   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
363
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
364
  EXPORT_SYMBOL_GPL(dccp_v4_send_check);
865e9022d   Gerrit Renker   [DCCP]: Remove re...
365
  static inline u64 dccp_v4_init_sequence(const struct sk_buff *skb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
366
  {
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
367
368
  	return secure_dccp_sequence_number(ip_hdr(skb)->daddr,
  					   ip_hdr(skb)->saddr,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
369
370
371
  					   dccp_hdr(skb)->dccph_dport,
  					   dccp_hdr(skb)->dccph_sport);
  }
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
372
373
374
375
376
377
  /*
   * The three way handshake has completed - we got a valid ACK or DATAACK -
   * now create the new socket.
   *
   * This is the equivalent of TCP's tcp_v4_syn_recv_sock
   */
0c27171e6   Eric Dumazet   tcp/dccp: constif...
378
379
  struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
  				       struct sk_buff *skb,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
380
  				       struct request_sock *req,
5e0724d02   Eric Dumazet   tcp/dccp: fix has...
381
382
383
  				       struct dst_entry *dst,
  				       struct request_sock *req_unhash,
  				       bool *own_req)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
384
385
386
  {
  	struct inet_request_sock *ireq;
  	struct inet_sock *newinet;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
387
388
389
390
  	struct sock *newsk;
  
  	if (sk_acceptq_is_full(sk))
  		goto exit_overflow;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
391
392
  	newsk = dccp_create_openreq_child(sk, req, skb);
  	if (newsk == NULL)
093d28232   Balazs Scheidler   tproxy: fix hash ...
393
  		goto exit_nonewsk;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
394

7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
395
396
  	newinet		   = inet_sk(newsk);
  	ireq		   = inet_rsk(req);
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
397
398
  	sk_daddr_set(newsk, ireq->ir_rmt_addr);
  	sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
634fb979e   Eric Dumazet   inet: includes a ...
399
  	newinet->inet_saddr	= ireq->ir_loc_addr;
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
400
  	RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
401
  	newinet->mc_index  = inet_iif(skb);
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
402
  	newinet->mc_ttl	   = ip_hdr(skb)->ttl;
c720c7e83   Eric Dumazet   inet: rename some...
403
  	newinet->inet_id   = jiffies;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
404

0e7344199   David S. Miller   ipv4: Use inet_cs...
405
406
407
408
  	if (dst == NULL && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL)
  		goto put_and_exit;
  
  	sk_setup_caps(newsk, dst);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
409
  	dccp_sync_mss(newsk, dst_mtu(dst));
0e7344199   David S. Miller   ipv4: Use inet_cs...
410
411
  	if (__inet_inherit_port(sk, newsk) < 0)
  		goto put_and_exit;
5e0724d02   Eric Dumazet   tcp/dccp: fix has...
412
  	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
413
414
415
416
  	if (*own_req)
  		ireq->ireq_opt = NULL;
  	else
  		newinet->inet_opt = NULL;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
417
418
419
  	return newsk;
  
  exit_overflow:
02a1d6e7a   Eric Dumazet   net: rename NET_{...
420
  	__NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
093d28232   Balazs Scheidler   tproxy: fix hash ...
421
422
  exit_nonewsk:
  	dst_release(dst);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
423
  exit:
02a1d6e7a   Eric Dumazet   net: rename NET_{...
424
  	__NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
425
  	return NULL;
0e7344199   David S. Miller   ipv4: Use inet_cs...
426
  put_and_exit:
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
427
  	newinet->inet_opt = NULL;
e337e24d6   Christoph Paasch   inet: Fix kmemlea...
428
429
  	inet_csk_prepare_forced_close(newsk);
  	dccp_done(newsk);
0e7344199   David S. Miller   ipv4: Use inet_cs...
430
  	goto exit;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
431
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
432
  EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
f54873982   Pavel Emelyanov   [NETNS][DCCPV4]: ...
433
  static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
434
435
436
  					   struct sk_buff *skb)
  {
  	struct rtable *rt;
898f73585   David S. Miller   dccp: Evaluate ip...
437
  	const struct iphdr *iph = ip_hdr(skb);
9d6ec9380   David S. Miller   ipv4: Use flowi4 ...
438
  	struct flowi4 fl4 = {
92101b3b2   David S. Miller   ipv4: Prepare for...
439
  		.flowi4_oif = inet_iif(skb),
898f73585   David S. Miller   dccp: Evaluate ip...
440
441
  		.daddr = iph->saddr,
  		.saddr = iph->daddr,
9d6ec9380   David S. Miller   ipv4: Use flowi4 ...
442
443
  		.flowi4_tos = RT_CONN_FLAGS(sk),
  		.flowi4_proto = sk->sk_protocol,
9cce96df5   David S. Miller   net: Put fl4_* ma...
444
445
  		.fl4_sport = dccp_hdr(skb)->dccph_dport,
  		.fl4_dport = dccp_hdr(skb)->dccph_sport,
1d28f42c1   David S. Miller   net: Put flowi_* ...
446
  	};
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
447

9d6ec9380   David S. Miller   ipv4: Use flowi4 ...
448
449
  	security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
  	rt = ip_route_output_flow(net, &fl4, sk);
b23dd4fe4   David S. Miller   ipv4: Make output...
450
  	if (IS_ERR(rt)) {
95556a883   Eric Dumazet   dccp: avoid deadl...
451
  		IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
452
453
  		return NULL;
  	}
d8d1f30b9   Changli Gao   net-next: remove ...
454
  	return &rt->dst;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
455
  }
ea3bea3a1   Eric Dumazet   tcp/dccp: constif...
456
  static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req)
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
457
458
459
  {
  	int err = -1;
  	struct sk_buff *skb;
fd80eb942   Denis V. Lunev   [INET]: Remove st...
460
  	struct dst_entry *dst;
6bd023f3d   David S. Miller   ipv4: Make caller...
461
  	struct flowi4 fl4;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
462

ba3f7f04e   David S. Miller   ipv4: Kill FLOWI_...
463
  	dst = inet_csk_route_req(sk, &fl4, req);
fd80eb942   Denis V. Lunev   [INET]: Remove st...
464
  	if (dst == NULL)
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
465
466
467
468
469
470
  		goto out;
  
  	skb = dccp_make_response(sk, dst, req);
  	if (skb != NULL) {
  		const struct inet_request_sock *ireq = inet_rsk(req);
  		struct dccp_hdr *dh = dccp_hdr(skb);
634fb979e   Eric Dumazet   inet: includes a ...
471
472
473
474
  		dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->ir_loc_addr,
  							      ireq->ir_rmt_addr);
  		err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
  					    ireq->ir_rmt_addr,
06f877d61   Eric Dumazet   tcp/dccp: fix oth...
475
  					    ireq_opt_deref(ireq));
b9df3cb8c   Gerrit Renker   [TCP/DCCP]: Intro...
476
  		err = net_xmit_eval(err);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
477
478
479
480
481
482
  	}
  
  out:
  	dst_release(dst);
  	return err;
  }
a00e74442   Eric Dumazet   tcp/dccp: constif...
483
  static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
484
485
  {
  	int err;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
486
  	const struct iphdr *rxiph;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
487
488
  	struct sk_buff *skb;
  	struct dst_entry *dst;
adf30907d   Eric Dumazet   net: skb->dst acc...
489
  	struct net *net = dev_net(skb_dst(rxskb)->dev);
b76c4b27f   Pavel Emelyanov   [NETNS][DCCPV4]: ...
490
  	struct sock *ctl_sk = net->dccp.v4_ctl_sk;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
491
492
  
  	/* Never send a reset in response to a reset. */
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
493
  	if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
494
  		return;
511c3f92a   Eric Dumazet   net: skb->rtable ...
495
  	if (skb_rtable(rxskb)->rt_type != RTN_LOCAL)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
496
  		return;
f54873982   Pavel Emelyanov   [NETNS][DCCPV4]: ...
497
  	dst = dccp_v4_route_skb(net, ctl_sk, rxskb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
498
499
  	if (dst == NULL)
  		return;
7b1cffa8c   Pavel Emelyanov   [NETNS][DCCPV4]: ...
500
  	skb = dccp_ctl_make_reset(ctl_sk, rxskb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
501
502
  	if (skb == NULL)
  		goto out;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
503
  	rxiph = ip_hdr(rxskb);
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
504
505
  	dccp_hdr(skb)->dccph_checksum = dccp_v4_csum_finish(skb, rxiph->saddr,
  								 rxiph->daddr);
adf30907d   Eric Dumazet   net: skb->dst acc...
506
  	skb_dst_set(skb, dst_clone(dst));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
507

95556a883   Eric Dumazet   dccp: avoid deadl...
508
  	local_bh_disable();
7b1cffa8c   Pavel Emelyanov   [NETNS][DCCPV4]: ...
509
510
  	bh_lock_sock(ctl_sk);
  	err = ip_build_and_send_pkt(skb, ctl_sk,
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
511
  				    rxiph->daddr, rxiph->saddr, NULL);
7b1cffa8c   Pavel Emelyanov   [NETNS][DCCPV4]: ...
512
  	bh_unlock_sock(ctl_sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
513

b9df3cb8c   Gerrit Renker   [TCP/DCCP]: Intro...
514
  	if (net_xmit_eval(err) == 0) {
95556a883   Eric Dumazet   dccp: avoid deadl...
515
516
  		__DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
  		__DCCP_INC_STATS(DCCP_MIB_OUTRSTS);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
517
  	}
95556a883   Eric Dumazet   dccp: avoid deadl...
518
  	local_bh_enable();
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
519
  out:
95556a883   Eric Dumazet   dccp: avoid deadl...
520
  	dst_release(dst);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
521
  }
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
522
523
  static void dccp_v4_reqsk_destructor(struct request_sock *req)
  {
d99a7bd21   Gerrit Renker   dccp: Cleanup rou...
524
  	dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
525
  	kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
526
  }
42cb80a23   Eric Dumazet   inet: remove sk_l...
527
  void dccp_syn_ack_timeout(const struct request_sock *req)
c72e11833   Eric Dumazet   inet: makes syn_a...
528
529
530
  {
  }
  EXPORT_SYMBOL(dccp_syn_ack_timeout);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
531
532
533
534
535
536
537
  static struct request_sock_ops dccp_request_sock_ops __read_mostly = {
  	.family		= PF_INET,
  	.obj_size	= sizeof(struct dccp_request_sock),
  	.rtx_syn_ack	= dccp_v4_send_response,
  	.send_ack	= dccp_reqsk_send_ack,
  	.destructor	= dccp_v4_reqsk_destructor,
  	.send_reset	= dccp_v4_ctl_send_reset,
c72e11833   Eric Dumazet   inet: makes syn_a...
538
  	.syn_ack_timeout = dccp_syn_ack_timeout,
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
539
540
541
542
543
  };
  
  int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
  {
  	struct inet_request_sock *ireq;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
544
545
  	struct request_sock *req;
  	struct dccp_request_sock *dreq;
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
546
  	const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
547
  	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
548
549
  
  	/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
511c3f92a   Eric Dumazet   net: skb->rtable ...
550
  	if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
4a5409a5a   Gerrit Renker   [DCCP]: Twice the...
551
  		return 0;	/* discard, don't send a reset here */
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
552
553
  
  	if (dccp_bad_service_code(sk, service)) {
4a5409a5a   Gerrit Renker   [DCCP]: Twice the...
554
  		dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
555
  		goto drop;
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
556
  	}
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
557
558
559
560
561
  	/*
  	 * TW buckets are converted to open requests without
  	 * limitations, they conserve resources and peer is
  	 * evidently real one.
  	 */
4a5409a5a   Gerrit Renker   [DCCP]: Twice the...
562
  	dcb->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
563
564
  	if (inet_csk_reqsk_queue_is_full(sk))
  		goto drop;
5ea8ea2cb   Eric Dumazet   tcp/dccp: drop SY...
565
  	if (sk_acceptq_is_full(sk))
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
566
  		goto drop;
a1a5344dd   Eric Dumazet   tcp: avoid two at...
567
  	req = inet_reqsk_alloc(&dccp_request_sock_ops, sk, true);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
568
569
  	if (req == NULL)
  		goto drop;
ac75773c2   Gerrit Renker   dccp: Per-socket ...
570
571
  	if (dccp_reqsk_init(req, dccp_sk(sk), skb))
  		goto drop_and_free;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
572

8b8194124   Gerrit Renker   [DCCP]: Allow to ...
573
574
575
  	dreq = dccp_rsk(req);
  	if (dccp_parse_options(sk, dreq, skb))
  		goto drop_and_free;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
576
577
578
579
  	if (security_inet_conn_request(sk, skb, req))
  		goto drop_and_free;
  
  	ireq = inet_rsk(req);
08d2cc3b2   Eric Dumazet   inet: request soc...
580
581
  	sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
  	sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
b855ff827   Eric Dumazet   dccp: initialize ...
582
  	ireq->ir_mark = inet_request_mark(sk, skb);
3f66b083a   Eric Dumazet   inet: introduce i...
583
  	ireq->ireq_family = AF_INET;
16f86165b   Eric Dumazet   inet: fill reques...
584
  	ireq->ir_iif = sk->sk_bound_dev_if;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
585

8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
586
  	/*
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
587
588
589
590
  	 * Step 3: Process LISTEN state
  	 *
  	 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
  	 *
f541fb7e2   Samuel Jero   dccp: fix bug in ...
591
  	 * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
592
  	 */
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
593
  	dreq->dreq_isr	   = dcb->dccpd_seq;
f541fb7e2   Samuel Jero   dccp: fix bug in ...
594
  	dreq->dreq_gsr	   = dreq->dreq_isr;
865e9022d   Gerrit Renker   [DCCP]: Remove re...
595
  	dreq->dreq_iss	   = dccp_v4_init_sequence(skb);
f541fb7e2   Samuel Jero   dccp: fix bug in ...
596
  	dreq->dreq_gss     = dreq->dreq_iss;
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
597
  	dreq->dreq_service = service;
1a2c6181c   Christoph Paasch   tcp: Remove TCPCT
598
  	if (dccp_v4_send_response(sk, req))
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
599
600
601
  		goto drop_and_free;
  
  	inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
b7953d3c0   Xin Long   dccp: fix a memle...
602
  	reqsk_put(req);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
603
604
605
606
607
  	return 0;
  
  drop_and_free:
  	reqsk_free(req);
  drop:
aa62d76b6   Eric Dumazet   dccp: rename DCCP...
608
  	__DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
609
610
  	return -1;
  }
3d2fe62b8   Gerrit Renker   [DCCPv4]: remove ...
611
  EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
612
613
614
615
616
617
618
619
620
621
622
623
  int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
  {
  	struct dccp_hdr *dh = dccp_hdr(skb);
  
  	if (sk->sk_state == DCCP_OPEN) { /* Fast path */
  		if (dccp_rcv_established(sk, skb, dh, skb->len))
  			goto reset;
  		return 0;
  	}
  
  	/*
  	 *  Step 3: Process LISTEN state
d83ca5acc   Gerrit Renker   [DCCP]: Update co...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  	 *	 If P.type == Request or P contains a valid Init Cookie option,
  	 *	      (* Must scan the packet's options to check for Init
  	 *		 Cookies.  Only Init Cookies are processed here,
  	 *		 however; other options are processed in Step 8.  This
  	 *		 scan need only be performed if the endpoint uses Init
  	 *		 Cookies *)
  	 *	      (* Generate a new socket and switch to that socket *)
  	 *	      Set S := new socket for this port pair
  	 *	      S.state = RESPOND
  	 *	      Choose S.ISS (initial seqno) or set from Init Cookies
  	 *	      Initialize S.GAR := S.ISS
  	 *	      Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
  	 *	      Continue with S.state == RESPOND
  	 *	      (* A Response packet will be generated in Step 11 *)
  	 *	 Otherwise,
  	 *	      Generate Reset(No Connection) unless P.type == Reset
  	 *	      Drop packet and return
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
641
  	 *
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
642
643
  	 * NOTE: the check for the packet types is done in
  	 *	 dccp_rcv_state_process
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
644
  	 */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
645
646
647
648
649
650
  
  	if (dccp_rcv_state_process(sk, skb, dh, skb->len))
  		goto reset;
  	return 0;
  
  reset:
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
651
  	dccp_v4_ctl_send_reset(sk, skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
652
653
654
  	kfree_skb(skb);
  	return 0;
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
655
  EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
656
657
658
659
660
  /**
   *	dccp_invalid_packet  -  check for malformed packets
   *	Implements RFC 4340, 8.5:  Step 1: Check header basics
   *	Packets that fail these checks are ignored and do not receive Resets.
   */
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
661
  int dccp_invalid_packet(struct sk_buff *skb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
662
663
  {
  	const struct dccp_hdr *dh;
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
664
  	unsigned int cscov;
648f0c28d   Eric Dumazet   net/dccp: fix use...
665
  	u8 dccph_doff;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
666
667
668
  
  	if (skb->pkt_type != PACKET_HOST)
  		return 1;
09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
669
  	/* If the packet is shorter than 12 bytes, drop packet and return */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
670
  	if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
59348b19e   Gerrit Renker   [DCCP]: Simplifie...
671
672
  		DCCP_WARN("pskb_may_pull failed
  ");
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
673
674
675
676
  		return 1;
  	}
  
  	dh = dccp_hdr(skb);
09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
677
  	/* If P.type is not understood, drop packet and return */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
678
  	if (dh->dccph_type >= DCCP_PKT_INVALID) {
59348b19e   Gerrit Renker   [DCCP]: Simplifie...
679
680
  		DCCP_WARN("invalid packet type
  ");
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
681
682
683
684
  		return 1;
  	}
  
  	/*
09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
685
  	 * If P.Data Offset is too small for packet type, drop packet and return
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
686
  	 */
648f0c28d   Eric Dumazet   net/dccp: fix use...
687
688
689
690
  	dccph_doff = dh->dccph_doff;
  	if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
  		DCCP_WARN("P.Data Offset(%u) too small
  ", dccph_doff);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
691
692
  		return 1;
  	}
09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
693
694
695
  	/*
  	 * If P.Data Offset is too too large for packet, drop packet and return
  	 */
648f0c28d   Eric Dumazet   net/dccp: fix use...
696
697
698
  	if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
  		DCCP_WARN("P.Data Offset(%u) too large
  ", dccph_doff);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
699
700
  		return 1;
  	}
648f0c28d   Eric Dumazet   net/dccp: fix use...
701
  	dh = dccp_hdr(skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
702
703
704
705
  	/*
  	 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
  	 * has short sequence numbers), drop packet and return
  	 */
6079a463c   Wei Yongjun   dccp: Fix to hand...
706
707
  	if ((dh->dccph_type < DCCP_PKT_DATA    ||
  	    dh->dccph_type > DCCP_PKT_DATAACK) && dh->dccph_x == 0)  {
59348b19e   Gerrit Renker   [DCCP]: Simplifie...
708
709
710
  		DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0
  ",
  			  dccp_packet_name(dh->dccph_type));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
711
712
  		return 1;
  	}
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
713
714
715
716
717
718
  	/*
  	 * If P.CsCov is too large for the packet size, drop packet and return.
  	 * This must come _before_ checksumming (not as RFC 4340 suggests).
  	 */
  	cscov = dccp_csum_coverage(skb);
  	if (cscov > skb->len) {
59348b19e   Gerrit Renker   [DCCP]: Simplifie...
719
720
721
  		DCCP_WARN("P.CsCov %u exceeds packet length %d
  ",
  			  dh->dccph_cscov, skb->len);
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
722
723
724
725
726
727
  		return 1;
  	}
  
  	/* If header checksum is incorrect, drop packet and return.
  	 * (This step is completed in the AF-dependent functions.) */
  	skb->csum = skb_checksum(skb, 0, cscov, 0);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
728
729
  	return 0;
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
730
  EXPORT_SYMBOL_GPL(dccp_invalid_packet);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
731
  /* this is called when real data arrives */
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
732
  static int dccp_v4_rcv(struct sk_buff *skb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
733
734
  {
  	const struct dccp_hdr *dh;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
735
  	const struct iphdr *iph;
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
736
  	bool refcounted;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
737
  	struct sock *sk;
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
738
  	int min_cov;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
739

6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
740
  	/* Step 1: Check header basics */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
741
742
743
  
  	if (dccp_invalid_packet(skb))
  		goto discard_it;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
744
  	iph = ip_hdr(skb);
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
745
  	/* Step 1: If header checksum is incorrect, drop packet and return */
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
746
  	if (dccp_v4_csum_finish(skb, iph->saddr, iph->daddr)) {
59348b19e   Gerrit Renker   [DCCP]: Simplifie...
747
748
  		DCCP_WARN("dropped packet with invalid checksum
  ");
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
749
750
  		goto discard_it;
  	}
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
751
  	dh = dccp_hdr(skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
752

fde20105f   Gerrit Renker   [DCCP]: Retrieve ...
753
  	DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
754
  	DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
21454aaad   Harvey Harrison   net: replace NIPQ...
755
  	dccp_pr_debug("%8.8s src=%pI4@%-5d dst=%pI4@%-5d seq=%llu",
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
756
  		      dccp_packet_name(dh->dccph_type),
21454aaad   Harvey Harrison   net: replace NIPQ...
757
758
  		      &iph->saddr, ntohs(dh->dccph_sport),
  		      &iph->daddr, ntohs(dh->dccph_dport),
f6ccf5541   David S. Miller   [DCCP]: Fix u64 p...
759
  		      (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
760
761
762
763
764
765
766
  
  	if (dccp_packet_without_ack(skb)) {
  		DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
  		dccp_pr_debug_cat("
  ");
  	} else {
  		DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
d23c7107b   Gerrit Renker   [DCCP]: Simplify ...
767
768
  		dccp_pr_debug_cat(", ack=%llu
  ", (unsigned long long)
f6ccf5541   David S. Miller   [DCCP]: Fix u64 p...
769
  				  DCCP_SKB_CB(skb)->dccpd_ack_seq);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
770
  	}
4bdc3d661   Eric Dumazet   tcp/dccp: fix beh...
771
  lookup:
a583636a8   Craig Gallek   inet: refactor in...
772
  	sk = __inet_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
3fa6f616a   David Ahern   net: ipv4: add se...
773
  			       dh->dccph_sport, dh->dccph_dport, 0, &refcounted);
4bdc3d661   Eric Dumazet   tcp/dccp: fix beh...
774
  	if (!sk) {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
775
776
777
778
779
  		dccp_pr_debug("failed to look up flow ID in table and "
  			      "get corresponding socket
  ");
  		goto no_dccp_socket;
  	}
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
780
  	/*
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
781
  	 * Step 2:
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
782
  	 *	... or S.state == TIMEWAIT,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
783
784
785
  	 *		Generate Reset(No Connection) unless P.type == Reset
  	 *		Drop packet and return
  	 */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
786
  	if (sk->sk_state == DCCP_TIME_WAIT) {
d23c7107b   Gerrit Renker   [DCCP]: Simplify ...
787
788
789
790
  		dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait
  ");
  		inet_twsk_put(inet_twsk(sk));
  		goto no_dccp_socket;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
791
  	}
079096f10   Eric Dumazet   tcp/dccp: install...
792
793
  	if (sk->sk_state == DCCP_NEW_SYN_RECV) {
  		struct request_sock *req = inet_reqsk(sk);
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
794
  		struct sock *nsk;
079096f10   Eric Dumazet   tcp/dccp: install...
795
796
  
  		sk = req->rsk_listener;
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
797
  		if (unlikely(sk->sk_state != DCCP_LISTEN)) {
f03f2e154   Eric Dumazet   tcp/dccp: add ine...
798
  			inet_csk_reqsk_queue_drop_and_put(sk, req);
4bdc3d661   Eric Dumazet   tcp/dccp: fix beh...
799
800
  			goto lookup;
  		}
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
801
  		sock_hold(sk);
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
802
  		refcounted = true;
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
803
  		nsk = dccp_check_req(sk, skb, req);
079096f10   Eric Dumazet   tcp/dccp: install...
804
805
  		if (!nsk) {
  			reqsk_put(req);
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
806
  			goto discard_and_relse;
079096f10   Eric Dumazet   tcp/dccp: install...
807
808
  		}
  		if (nsk == sk) {
079096f10   Eric Dumazet   tcp/dccp: install...
809
810
811
  			reqsk_put(req);
  		} else if (dccp_child_process(sk, nsk, skb)) {
  			dccp_v4_ctl_send_reset(sk, skb);
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
812
  			goto discard_and_relse;
079096f10   Eric Dumazet   tcp/dccp: install...
813
  		} else {
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
814
  			sock_put(sk);
079096f10   Eric Dumazet   tcp/dccp: install...
815
816
817
  			return 0;
  		}
  	}
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
818
819
  	/*
  	 * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
820
821
  	 *	o if MinCsCov = 0, only packets with CsCov = 0 are accepted
  	 *	o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
822
823
824
825
826
827
828
829
830
831
832
  	 */
  	min_cov = dccp_sk(sk)->dccps_pcrlen;
  	if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov))  {
  		dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d
  ",
  			      dh->dccph_cscov, min_cov);
  		/* FIXME: "Such packets SHOULD be reported using Data Dropped
  		 *         options (Section 11.7) with Drop Code 0, Protocol
  		 *         Constraints."                                     */
  		goto discard_and_relse;
  	}
25995ff57   Arnaldo Carvalho de Melo   [SOCK]: Introduce...
833
  	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
834
  		goto discard_and_relse;
eb9c7ebe6   Patrick McHardy   [NETFILTER]: Hand...
835
  	nf_reset(skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
836

c3f24cfb3   Eric Dumazet   dccp: do not rele...
837
  	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4, refcounted);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
838
839
840
841
842
843
  
  no_dccp_socket:
  	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
  		goto discard_it;
  	/*
  	 * Step 2:
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
844
  	 *	If no socket ...
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
845
846
847
848
  	 *		Generate Reset(No Connection) unless P.type == Reset
  	 *		Drop packet and return
  	 */
  	if (dh->dccph_type != DCCP_PKT_RESET) {
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
849
850
  		DCCP_SKB_CB(skb)->dccpd_reset_code =
  					DCCP_RESET_CODE_NO_CONNECTION;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
851
  		dccp_v4_ctl_send_reset(sk, skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
852
853
854
  	}
  
  discard_it:
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
855
856
857
858
  	kfree_skb(skb);
  	return 0;
  
  discard_and_relse:
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
859
860
  	if (refcounted)
  		sock_put(sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
861
862
  	goto discard_it;
  }
3b401a81c   Stephen Hemminger   inet: inet_connec...
863
  static const struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
864
865
866
867
868
869
870
871
872
873
  	.queue_xmit	   = ip_queue_xmit,
  	.send_check	   = dccp_v4_send_check,
  	.rebuild_header	   = inet_sk_rebuild_header,
  	.conn_request	   = dccp_v4_conn_request,
  	.syn_recv_sock	   = dccp_v4_request_recv_sock,
  	.net_header_len	   = sizeof(struct iphdr),
  	.setsockopt	   = ip_setsockopt,
  	.getsockopt	   = ip_getsockopt,
  	.addr2sockaddr	   = inet_csk_addr2sockaddr,
  	.sockaddr_len	   = sizeof(struct sockaddr_in),
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
874
  #ifdef CONFIG_COMPAT
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
875
876
  	.compat_setsockopt = compat_ip_setsockopt,
  	.compat_getsockopt = compat_ip_getsockopt,
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
877
  #endif
57cca05af   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
878
  };
3e0fadc51   Arnaldo Carvalho de Melo   [DCCP]: Move dccp...
879
  static int dccp_v4_init_sock(struct sock *sk)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
880
  {
724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
881
882
  	static __u8 dccp_v4_ctl_sock_initialized;
  	int err = dccp_init_sock(sk, dccp_v4_ctl_sock_initialized);
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
883

724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
884
885
886
  	if (err == 0) {
  		if (unlikely(!dccp_v4_ctl_sock_initialized))
  			dccp_v4_ctl_sock_initialized = 1;
3e0fadc51   Arnaldo Carvalho de Melo   [DCCP]: Move dccp...
887
  		inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops;
724788735   Arnaldo Carvalho de Melo   [DCCP] ipv6: Add ...
888
  	}
3e0fadc51   Arnaldo Carvalho de Melo   [DCCP]: Move dccp...
889
  	return err;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
890
  }
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
891
892
893
  static struct timewait_sock_ops dccp_timewait_sock_ops = {
  	.twsk_obj_size	= sizeof(struct inet_timewait_sock),
  };
5e0817f84   Adrian Bunk   [DCCP] ipv4: make...
894
  static struct proto dccp_v4_prot = {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
895
896
897
898
899
900
901
902
903
904
905
906
  	.name			= "DCCP",
  	.owner			= THIS_MODULE,
  	.close			= dccp_close,
  	.connect		= dccp_v4_connect,
  	.disconnect		= dccp_disconnect,
  	.ioctl			= dccp_ioctl,
  	.init			= dccp_v4_init_sock,
  	.setsockopt		= dccp_setsockopt,
  	.getsockopt		= dccp_getsockopt,
  	.sendmsg		= dccp_sendmsg,
  	.recvmsg		= dccp_recvmsg,
  	.backlog_rcv		= dccp_v4_do_rcv,
ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
907
908
  	.hash			= inet_hash,
  	.unhash			= inet_unhash,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
909
  	.accept			= inet_csk_accept,
ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
910
  	.get_port		= inet_csk_get_port,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
911
  	.shutdown		= dccp_shutdown,
3e0fadc51   Arnaldo Carvalho de Melo   [DCCP]: Move dccp...
912
  	.destroy		= dccp_destroy_sock,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
913
914
915
  	.orphan_count		= &dccp_orphan_count,
  	.max_header		= MAX_DCCP_HEADER,
  	.obj_size		= sizeof(struct dccp_sock),
5f0d5a3ae   Paul E. McKenney   mm: Rename SLAB_D...
916
  	.slab_flags		= SLAB_TYPESAFE_BY_RCU,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
917
  	.rsk_prot		= &dccp_request_sock_ops,
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
918
  	.twsk_prot		= &dccp_timewait_sock_ops,
39d8cda76   Pavel Emelyanov   [SOCK]: Add udp_h...
919
  	.h.hashinfo		= &dccp_hashinfo,
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
920
921
922
923
  #ifdef CONFIG_COMPAT
  	.compat_setsockopt	= compat_dccp_setsockopt,
  	.compat_getsockopt	= compat_dccp_getsockopt,
  #endif
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
924
  };
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
925

32613090a   Alexey Dobriyan   net: constify str...
926
  static const struct net_protocol dccp_v4_protocol = {
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
927
928
929
  	.handler	= dccp_v4_rcv,
  	.err_handler	= dccp_v4_err,
  	.no_policy	= 1,
fc5f8580d   Pavel Emelyanov   [NETNS][DCCPV4]: ...
930
  	.netns_ok	= 1,
8ed1dc44d   Hannes Frederic Sowa   ipv4: introduce h...
931
  	.icmp_strict_tag_validation = 1,
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
932
933
934
  };
  
  static const struct proto_ops inet_dccp_ops = {
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
935
936
937
938
939
940
941
942
  	.family		   = PF_INET,
  	.owner		   = THIS_MODULE,
  	.release	   = inet_release,
  	.bind		   = inet_bind,
  	.connect	   = inet_stream_connect,
  	.socketpair	   = sock_no_socketpair,
  	.accept		   = inet_accept,
  	.getname	   = inet_getname,
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
943
  	/* FIXME: work on tcp_poll to rename it to inet_csk_poll */
f4335f52b   Christoph Hellwig   net/dccp: convert...
944
  	.poll_mask	   = dccp_poll_mask,
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
945
  	.ioctl		   = inet_ioctl,
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
946
  	/* FIXME: work on inet_listen to rename it to sock_common_listen */
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
947
948
949
950
951
952
953
954
  	.listen		   = inet_dccp_listen,
  	.shutdown	   = inet_shutdown,
  	.setsockopt	   = sock_common_setsockopt,
  	.getsockopt	   = sock_common_getsockopt,
  	.sendmsg	   = inet_sendmsg,
  	.recvmsg	   = sock_common_recvmsg,
  	.mmap		   = sock_no_mmap,
  	.sendpage	   = sock_no_sendpage,
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
955
  #ifdef CONFIG_COMPAT
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
956
957
  	.compat_setsockopt = compat_sock_common_setsockopt,
  	.compat_getsockopt = compat_sock_common_getsockopt,
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
958
  #endif
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
959
960
961
962
963
964
965
  };
  
  static struct inet_protosw dccp_v4_protosw = {
  	.type		= SOCK_DCCP,
  	.protocol	= IPPROTO_DCCP,
  	.prot		= &dccp_v4_prot,
  	.ops		= &inet_dccp_ops,
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
966
967
  	.flags		= INET_PROTOSW_ICSK,
  };
2c8c1e729   Alexey Dobriyan   net: spread __net...
968
  static int __net_init dccp_v4_init_net(struct net *net)
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
969
  {
d14a0ebda   Gerrit Renker   net-2.6 [Bug-Fix]...
970
971
  	if (dccp_hashinfo.bhash == NULL)
  		return -ESOCKTNOSUPPORT;
b76c4b27f   Pavel Emelyanov   [NETNS][DCCPV4]: ...
972

d14a0ebda   Gerrit Renker   net-2.6 [Bug-Fix]...
973
974
  	return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
  				    SOCK_DCCP, IPPROTO_DCCP, net);
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
975
  }
2c8c1e729   Alexey Dobriyan   net: spread __net...
976
  static void __net_exit dccp_v4_exit_net(struct net *net)
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
977
  {
b76c4b27f   Pavel Emelyanov   [NETNS][DCCPV4]: ...
978
  	inet_ctl_sock_destroy(net->dccp.v4_ctl_sk);
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
979
  }
ec7cb62d1   Andrey Ryabinin   net/dccp: fix use...
980
981
982
983
  static void __net_exit dccp_v4_exit_batch(struct list_head *net_exit_list)
  {
  	inet_twsk_purge(&dccp_hashinfo, AF_INET);
  }
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
984
985
986
  static struct pernet_operations dccp_v4_ops = {
  	.init	= dccp_v4_init_net,
  	.exit	= dccp_v4_exit_net,
ec7cb62d1   Andrey Ryabinin   net/dccp: fix use...
987
  	.exit_batch = dccp_v4_exit_batch,
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
988
  };
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
989
990
991
  static int __init dccp_v4_init(void)
  {
  	int err = proto_register(&dccp_v4_prot, 1);
d5494acb8   Xin Long   dccp: call inet_a...
992
  	if (err)
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
993
  		goto out;
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
994
  	inet_register_protosw(&dccp_v4_protosw);
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
995
996
997
  	err = register_pernet_subsys(&dccp_v4_ops);
  	if (err)
  		goto out_destroy_ctl_sock;
d5494acb8   Xin Long   dccp: call inet_a...
998
999
1000
1001
  
  	err = inet_add_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
  	if (err)
  		goto out_proto_unregister;
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1002
1003
  out:
  	return err;
d5494acb8   Xin Long   dccp: call inet_a...
1004
1005
  out_proto_unregister:
  	unregister_pernet_subsys(&dccp_v4_ops);
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
1006
  out_destroy_ctl_sock:
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1007
  	inet_unregister_protosw(&dccp_v4_protosw);
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1008
1009
1010
1011
1012
1013
  	proto_unregister(&dccp_v4_prot);
  	goto out;
  }
  
  static void __exit dccp_v4_exit(void)
  {
d5494acb8   Xin Long   dccp: call inet_a...
1014
  	inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
72a2d6138   Pavel Emelyanov   [NETNS][DCCPV4]: ...
1015
  	unregister_pernet_subsys(&dccp_v4_ops);
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1016
  	inet_unregister_protosw(&dccp_v4_protosw);
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
  	proto_unregister(&dccp_v4_prot);
  }
  
  module_init(dccp_v4_init);
  module_exit(dccp_v4_exit);
  
  /*
   * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
   * values directly, Also cover the case where the protocol is not specified,
   * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
   */
7131c6c73   Jean Delvare   [INET]: Use MODUL...
1028
1029
  MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6);
  MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6);
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
1030
1031
1032
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
  MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");