dt-bindings: mvebu-odmi: Fix example typo
[linux-2.6-block.git] / net / dccp / ipv6.c
CommitLineData
3df80d93
ACM
1/*
2 * DCCP over IPv6
45329e71 3 * Linux INET6 implementation
3df80d93
ACM
4 *
5 * Based on net/dccp6/ipv6.c
6 *
7 * Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
3df80d93
ACM
15#include <linux/module.h>
16#include <linux/random.h>
5a0e3ad6 17#include <linux/slab.h>
3df80d93
ACM
18#include <linux/xfrm.h>
19
20#include <net/addrconf.h>
21#include <net/inet_common.h>
22#include <net/inet_hashtables.h>
14c85021 23#include <net/inet_sock.h>
3df80d93
ACM
24#include <net/inet6_connection_sock.h>
25#include <net/inet6_hashtables.h>
26#include <net/ip6_route.h>
27#include <net/ipv6.h>
28#include <net/protocol.h>
29#include <net/transp_v6.h>
aa0e4e4a 30#include <net/ip6_checksum.h>
3df80d93 31#include <net/xfrm.h>
6e5714ea 32#include <net/secure_seq.h>
3df80d93
ACM
33
34#include "dccp.h"
35#include "ipv6.h"
4b79f0af 36#include "feat.h"
3df80d93 37
13f51d82 38/* The per-net dccp.v6_ctl_sk is used for sending RSTs and ACKs */
72478873 39
3b401a81
SH
40static const struct inet_connection_sock_af_ops dccp_ipv6_mapped;
41static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
3df80d93 42
6f4e5fff 43/* add pseudo-header to DCCP checksum stored in skb->csum */
868c86bc 44static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
b71d1d42
ED
45 const struct in6_addr *saddr,
46 const struct in6_addr *daddr)
3df80d93 47{
6f4e5fff
GR
48 return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
49}
50
bb296246 51static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb)
6f4e5fff
GR
52{
53 struct ipv6_pinfo *np = inet6_sk(sk);
54 struct dccp_hdr *dh = dccp_hdr(skb);
55
56 dccp_csum_outgoing(skb);
efe4208f 57 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &sk->sk_v6_daddr);
3df80d93
ACM
58}
59
6e5714ea 60static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
d7f7365f 61{
0660e03f
ACM
62 return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
63 ipv6_hdr(skb)->saddr.s6_addr32,
d7f7365f
GR
64 dccp_hdr(skb)->dccph_dport,
65 dccp_hdr(skb)->dccph_sport );
66
3df80d93
ACM
67}
68
3df80d93 69static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
d5fdd6ba 70 u8 type, u8 code, int offset, __be32 info)
3df80d93 71{
b71d1d42 72 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
3df80d93 73 const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
e0bcfb0c 74 struct dccp_sock *dp;
3df80d93
ACM
75 struct ipv6_pinfo *np;
76 struct sock *sk;
77 int err;
78 __u64 seq;
ca12a1a4 79 struct net *net = dev_net(skb->dev);
3df80d93 80
860239c5
WY
81 if (skb->len < offset + sizeof(*dh) ||
82 skb->len < offset + __dccp_basic_hdr_len(dh)) {
a16292a0
ED
83 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
84 ICMP6_MIB_INERRORS);
860239c5
WY
85 return;
86 }
87
52036a43
ED
88 sk = __inet6_lookup_established(net, &dccp_hashinfo,
89 &hdr->daddr, dh->dccph_dport,
90 &hdr->saddr, ntohs(dh->dccph_sport),
91 inet6_iif(skb));
3df80d93 92
52036a43 93 if (!sk) {
a16292a0
ED
94 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
95 ICMP6_MIB_INERRORS);
3df80d93
ACM
96 return;
97 }
98
99 if (sk->sk_state == DCCP_TIME_WAIT) {
9469c7b4 100 inet_twsk_put(inet_twsk(sk));
3df80d93
ACM
101 return;
102 }
52036a43
ED
103 seq = dccp_hdr_seq(dh);
104 if (sk->sk_state == DCCP_NEW_SYN_RECV)
105 return dccp_req_err(sk, seq);
3df80d93
ACM
106
107 bh_lock_sock(sk);
108 if (sock_owned_by_user(sk))
02a1d6e7 109 __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS);
3df80d93
ACM
110
111 if (sk->sk_state == DCCP_CLOSED)
112 goto out;
113
e0bcfb0c 114 dp = dccp_sk(sk);
e0bcfb0c
WY
115 if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
116 !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
02a1d6e7 117 __NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
e0bcfb0c
WY
118 goto out;
119 }
120
3df80d93
ACM
121 np = inet6_sk(sk);
122
ec18d9a2
DM
123 if (type == NDISC_REDIRECT) {
124 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
125
1ed5c48f 126 if (dst)
6700c270 127 dst->ops->redirect(dst, sk, skb);
bd784a14 128 goto out;
ec18d9a2
DM
129 }
130
3df80d93 131 if (type == ICMPV6_PKT_TOOBIG) {
3df80d93
ACM
132 struct dst_entry *dst = NULL;
133
93b36cf3
HFS
134 if (!ip6_sk_accept_pmtu(sk))
135 goto out;
136
3df80d93
ACM
137 if (sock_owned_by_user(sk))
138 goto out;
139 if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
140 goto out;
141
35ad9b9c
DM
142 dst = inet6_csk_update_pmtu(sk, ntohl(info));
143 if (!dst)
144 goto out;
145
146 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst))
3df80d93 147 dccp_sync_mss(sk, dst_mtu(dst));
3df80d93
ACM
148 goto out;
149 }
150
151 icmpv6_err_convert(type, code, &err);
152
3df80d93
ACM
153 /* Might be for an request_sock */
154 switch (sk->sk_state) {
3df80d93
ACM
155 case DCCP_REQUESTING:
156 case DCCP_RESPOND: /* Cannot happen.
45329e71 157 It can, it SYNs are crossed. --ANK */
3df80d93 158 if (!sock_owned_by_user(sk)) {
aa62d76b 159 __DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
3df80d93
ACM
160 sk->sk_err = err;
161 /*
162 * Wake people up to see the error
163 * (see connect in sock.c)
164 */
165 sk->sk_error_report(sk);
3df80d93
ACM
166 dccp_done(sk);
167 } else
168 sk->sk_err_soft = err;
169 goto out;
170 }
171
172 if (!sock_owned_by_user(sk) && np->recverr) {
173 sk->sk_err = err;
174 sk->sk_error_report(sk);
175 } else
176 sk->sk_err_soft = err;
177
178out:
179 bh_unlock_sock(sk);
180 sock_put(sk);
181}
182
183
ea3bea3a 184static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req)
3df80d93 185{
634fb979 186 struct inet_request_sock *ireq = inet_rsk(req);
3df80d93
ACM
187 struct ipv6_pinfo *np = inet6_sk(sk);
188 struct sk_buff *skb;
20c59de2 189 struct in6_addr *final_p, final;
4c9483b2 190 struct flowi6 fl6;
3df80d93 191 int err = -1;
fd80eb94 192 struct dst_entry *dst;
3df80d93 193
4c9483b2
DM
194 memset(&fl6, 0, sizeof(fl6));
195 fl6.flowi6_proto = IPPROTO_DCCP;
634fb979
ED
196 fl6.daddr = ireq->ir_v6_rmt_addr;
197 fl6.saddr = ireq->ir_v6_loc_addr;
4c9483b2 198 fl6.flowlabel = 0;
634fb979
ED
199 fl6.flowi6_oif = ireq->ir_iif;
200 fl6.fl6_dport = ireq->ir_rmt_port;
b44084c2 201 fl6.fl6_sport = htons(ireq->ir_num);
4c9483b2 202 security_req_classify_flow(req, flowi6_to_flowi(&fl6));
3df80d93 203
3df80d93 204
45f6fad8
ED
205 rcu_read_lock();
206 final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
207 rcu_read_unlock();
3df80d93 208
0e0d44ab 209 dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
68d0c6d3
DM
210 if (IS_ERR(dst)) {
211 err = PTR_ERR(dst);
212 dst = NULL;
fd80eb94 213 goto done;
68d0c6d3 214 }
3df80d93
ACM
215
216 skb = dccp_make_response(sk, dst, req);
217 if (skb != NULL) {
218 struct dccp_hdr *dh = dccp_hdr(skb);
56ac42bc 219 struct ipv6_txoptions *opt;
45329e71 220
6f4e5fff 221 dh->dccph_checksum = dccp_v6_csum_finish(skb,
634fb979
ED
222 &ireq->ir_v6_loc_addr,
223 &ireq->ir_v6_rmt_addr);
224 fl6.daddr = ireq->ir_v6_rmt_addr;
45f6fad8 225 rcu_read_lock();
56ac42bc
HD
226 opt = ireq->ipv6_opt;
227 if (!opt)
228 opt = rcu_dereference(np->opt);
229 err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
45f6fad8 230 rcu_read_unlock();
b9df3cb8 231 err = net_xmit_eval(err);
3df80d93
ACM
232 }
233
234done:
0cbd7825 235 dst_release(dst);
3df80d93
ACM
236 return err;
237}
238
239static void dccp_v6_reqsk_destructor(struct request_sock *req)
240{
d99a7bd2 241 dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
56ac42bc 242 kfree(inet_rsk(req)->ipv6_opt);
634fb979 243 kfree_skb(inet_rsk(req)->pktopts);
3df80d93
ACM
244}
245
a00e7444 246static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
3df80d93 247{
b71d1d42 248 const struct ipv6hdr *rxip6h;
3df80d93 249 struct sk_buff *skb;
4c9483b2 250 struct flowi6 fl6;
adf30907 251 struct net *net = dev_net(skb_dst(rxskb)->dev);
334527d3 252 struct sock *ctl_sk = net->dccp.v6_ctl_sk;
adf30907 253 struct dst_entry *dst;
3df80d93 254
e356d37a 255 if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
3df80d93
ACM
256 return;
257
258 if (!ipv6_unicast_destination(rxskb))
45329e71 259 return;
3df80d93 260
02047741 261 skb = dccp_ctl_make_reset(ctl_sk, rxskb);
45329e71 262 if (skb == NULL)
8109b02b 263 return;
3df80d93 264
0660e03f 265 rxip6h = ipv6_hdr(rxskb);
e356d37a
GR
266 dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr,
267 &rxip6h->daddr);
6f4e5fff 268
4c9483b2 269 memset(&fl6, 0, sizeof(fl6));
4e3fd7a0
AD
270 fl6.daddr = rxip6h->saddr;
271 fl6.saddr = rxip6h->daddr;
6f4e5fff 272
4c9483b2
DM
273 fl6.flowi6_proto = IPPROTO_DCCP;
274 fl6.flowi6_oif = inet6_iif(rxskb);
1958b856
DM
275 fl6.fl6_dport = dccp_hdr(skb)->dccph_dport;
276 fl6.fl6_sport = dccp_hdr(skb)->dccph_sport;
4c9483b2 277 security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
3df80d93
ACM
278
279 /* sk = NULL, but it is safe for now. RST socket required. */
0e0d44ab 280 dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL);
68d0c6d3
DM
281 if (!IS_ERR(dst)) {
282 skb_dst_set(skb, dst);
b903d324 283 ip6_xmit(ctl_sk, skb, &fl6, NULL, 0);
7309f882
ED
284 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
285 DCCP_INC_STATS(DCCP_MIB_OUTRSTS);
68d0c6d3 286 return;
3df80d93
ACM
287 }
288
289 kfree_skb(skb);
290}
291
73c9e02c
GR
292static struct request_sock_ops dccp6_request_sock_ops = {
293 .family = AF_INET6,
294 .obj_size = sizeof(struct dccp6_request_sock),
295 .rtx_syn_ack = dccp_v6_send_response,
296 .send_ack = dccp_reqsk_send_ack,
297 .destructor = dccp_v6_reqsk_destructor,
298 .send_reset = dccp_v6_ctl_send_reset,
c72e1183 299 .syn_ack_timeout = dccp_syn_ack_timeout,
73c9e02c
GR
300};
301
3df80d93
ACM
302static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
303{
3df80d93
ACM
304 struct request_sock *req;
305 struct dccp_request_sock *dreq;
634fb979 306 struct inet_request_sock *ireq;
3df80d93 307 struct ipv6_pinfo *np = inet6_sk(sk);
8109b02b 308 const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
3df80d93 309 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
3df80d93
ACM
310
311 if (skb->protocol == htons(ETH_P_IP))
312 return dccp_v4_conn_request(sk, skb);
313
314 if (!ipv6_unicast_destination(skb))
4a5409a5 315 return 0; /* discard, don't send a reset here */
3df80d93
ACM
316
317 if (dccp_bad_service_code(sk, service)) {
4a5409a5 318 dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
3df80d93 319 goto drop;
8109b02b 320 }
3df80d93 321 /*
45329e71 322 * There are no SYN attacks on IPv6, yet...
3df80d93 323 */
4a5409a5 324 dcb->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
3df80d93 325 if (inet_csk_reqsk_queue_is_full(sk))
45329e71 326 goto drop;
3df80d93
ACM
327
328 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
329 goto drop;
330
a1a5344d 331 req = inet_reqsk_alloc(&dccp6_request_sock_ops, sk, true);
3df80d93
ACM
332 if (req == NULL)
333 goto drop;
334
ac75773c
GR
335 if (dccp_reqsk_init(req, dccp_sk(sk), skb))
336 goto drop_and_free;
3df80d93 337
8b819412
GR
338 dreq = dccp_rsk(req);
339 if (dccp_parse_options(sk, dreq, skb))
340 goto drop_and_free;
341
4237c75c
VY
342 if (security_inet_conn_request(sk, skb, req))
343 goto drop_and_free;
344
634fb979
ED
345 ireq = inet_rsk(req);
346 ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
347 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
3f66b083 348 ireq->ireq_family = AF_INET6;
3df80d93 349
a224772d 350 if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) ||
3df80d93
ACM
351 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
352 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
353 atomic_inc(&skb->users);
634fb979 354 ireq->pktopts = skb;
3df80d93 355 }
634fb979 356 ireq->ir_iif = sk->sk_bound_dev_if;
3df80d93
ACM
357
358 /* So that link locals have meaning */
359 if (!sk->sk_bound_dev_if &&
634fb979
ED
360 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
361 ireq->ir_iif = inet6_iif(skb);
3df80d93 362
45329e71 363 /*
3df80d93
ACM
364 * Step 3: Process LISTEN state
365 *
d83ca5ac 366 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
3df80d93 367 *
f541fb7e 368 * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
3df80d93 369 */
3df80d93 370 dreq->dreq_isr = dcb->dccpd_seq;
f541fb7e 371 dreq->dreq_gsr = dreq->dreq_isr;
865e9022 372 dreq->dreq_iss = dccp_v6_init_sequence(skb);
f541fb7e 373 dreq->dreq_gss = dreq->dreq_iss;
3df80d93
ACM
374 dreq->dreq_service = service;
375
1a2c6181 376 if (dccp_v6_send_response(sk, req))
3df80d93
ACM
377 goto drop_and_free;
378
079096f1 379 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
3df80d93
ACM
380 return 0;
381
382drop_and_free:
383 reqsk_free(req);
384drop:
aa62d76b 385 __DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
3df80d93
ACM
386 return -1;
387}
388
0c27171e 389static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
3df80d93
ACM
390 struct sk_buff *skb,
391 struct request_sock *req,
5e0724d0
ED
392 struct dst_entry *dst,
393 struct request_sock *req_unhash,
394 bool *own_req)
3df80d93 395{
634fb979 396 struct inet_request_sock *ireq = inet_rsk(req);
0c27171e
ED
397 struct ipv6_pinfo *newnp;
398 const struct ipv6_pinfo *np = inet6_sk(sk);
45f6fad8 399 struct ipv6_txoptions *opt;
3df80d93 400 struct inet_sock *newinet;
3df80d93
ACM
401 struct dccp6_sock *newdp6;
402 struct sock *newsk;
3df80d93
ACM
403
404 if (skb->protocol == htons(ETH_P_IP)) {
405 /*
406 * v6 mapped
407 */
5e0724d0
ED
408 newsk = dccp_v4_request_recv_sock(sk, skb, req, dst,
409 req_unhash, own_req);
45329e71 410 if (newsk == NULL)
3df80d93
ACM
411 return NULL;
412
413 newdp6 = (struct dccp6_sock *)newsk;
3df80d93
ACM
414 newinet = inet_sk(newsk);
415 newinet->pinet6 = &newdp6->inet6;
416 newnp = inet6_sk(newsk);
417
418 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
419
d1e559d0 420 newnp->saddr = newsk->sk_v6_rcv_saddr;
3df80d93
ACM
421
422 inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
423 newsk->sk_backlog_rcv = dccp_v4_do_rcv;
424 newnp->pktoptions = NULL;
425 newnp->opt = NULL;
426 newnp->mcast_oif = inet6_iif(skb);
0660e03f 427 newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
3df80d93
ACM
428
429 /*
430 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
431 * here, dccp_create_openreq_child now does this for us, see the comment in
432 * that function for the gory details. -acme
433 */
434
435 /* It is tricky place. Until this moment IPv4 tcp
436 worked with IPv6 icsk.icsk_af_ops.
437 Sync it now.
438 */
d83d8461 439 dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
3df80d93
ACM
440
441 return newsk;
442 }
443
3df80d93
ACM
444
445 if (sk_acceptq_is_full(sk))
446 goto out_overflow;
447
f76b33c3 448 if (!dst) {
4c9483b2
DM
449 struct flowi6 fl6;
450
f76b33c3
ED
451 dst = inet6_csk_route_req(sk, &fl6, req, IPPROTO_DCCP);
452 if (!dst)
3df80d93 453 goto out;
45329e71 454 }
3df80d93
ACM
455
456 newsk = dccp_create_openreq_child(sk, req, skb);
457 if (newsk == NULL)
093d2823 458 goto out_nonewsk;
3df80d93
ACM
459
460 /*
461 * No need to charge this sock to the relevant IPv6 refcnt debug socks
462 * count here, dccp_create_openreq_child now does this for us, see the
463 * comment in that function for the gory details. -acme
464 */
465
6bd4f355 466 ip6_dst_store(newsk, dst, NULL, NULL);
45329e71
ACM
467 newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
468 NETIF_F_TSO);
3df80d93
ACM
469 newdp6 = (struct dccp6_sock *)newsk;
470 newinet = inet_sk(newsk);
471 newinet->pinet6 = &newdp6->inet6;
3df80d93
ACM
472 newnp = inet6_sk(newsk);
473
474 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
475
634fb979
ED
476 newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr;
477 newnp->saddr = ireq->ir_v6_loc_addr;
478 newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr;
479 newsk->sk_bound_dev_if = ireq->ir_iif;
3df80d93 480
45329e71 481 /* Now IPv6 options...
3df80d93
ACM
482
483 First: no IPv4 options.
484 */
f6d8bd05 485 newinet->inet_opt = NULL;
3df80d93
ACM
486
487 /* Clone RX bits */
488 newnp->rxopt.all = np->rxopt.all;
489
3df80d93 490 newnp->pktoptions = NULL;
3df80d93
ACM
491 newnp->opt = NULL;
492 newnp->mcast_oif = inet6_iif(skb);
0660e03f 493 newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
3df80d93 494
45329e71
ACM
495 /*
496 * Clone native IPv6 options from listening socket (if any)
497 *
498 * Yes, keeping reference count would be much more clever, but we make
499 * one more one thing there: reattach optmem to newsk.
3df80d93 500 */
56ac42bc
HD
501 opt = ireq->ipv6_opt;
502 if (!opt)
503 opt = rcu_dereference(np->opt);
45f6fad8
ED
504 if (opt) {
505 opt = ipv6_dup_options(newsk, opt);
506 RCU_INIT_POINTER(newnp->opt, opt);
507 }
d83d8461 508 inet_csk(newsk)->icsk_ext_hdr_len = 0;
45f6fad8
ED
509 if (opt)
510 inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
511 opt->opt_flen;
3df80d93
ACM
512
513 dccp_sync_mss(newsk, dst_mtu(dst));
514
c720c7e8
ED
515 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
516 newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
3df80d93 517
093d2823 518 if (__inet_inherit_port(sk, newsk) < 0) {
e337e24d
CP
519 inet_csk_prepare_forced_close(newsk);
520 dccp_done(newsk);
093d2823
BS
521 goto out;
522 }
5e0724d0 523 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
ce105008
ED
524 /* Clone pktoptions received with SYN, if we own the req */
525 if (*own_req && ireq->pktopts) {
526 newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC);
527 consume_skb(ireq->pktopts);
528 ireq->pktopts = NULL;
529 if (newnp->pktoptions)
530 skb_set_owner_r(newnp->pktoptions, newsk);
531 }
3df80d93
ACM
532
533 return newsk;
534
535out_overflow:
02a1d6e7 536 __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
093d2823
BS
537out_nonewsk:
538 dst_release(dst);
3df80d93 539out:
02a1d6e7 540 __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
3df80d93
ACM
541 return NULL;
542}
543
544/* The socket must have it's spinlock held when we get
545 * here.
546 *
547 * We have a potential double-lock case here, so even when
548 * doing backlog processing we use the BH locking scheme.
549 * This is because we cannot sleep with the original spinlock
550 * held.
551 */
552static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
553{
554 struct ipv6_pinfo *np = inet6_sk(sk);
555 struct sk_buff *opt_skb = NULL;
556
557 /* Imagine: socket is IPv6. IPv4 packet arrives,
558 goes to IPv4 receive handler and backlogged.
559 From backlog it always goes here. Kerboom...
560 Fortunately, dccp_rcv_established and rcv_established
561 handle them correctly, but it is not case with
562 dccp_v6_hnd_req and dccp_v6_ctl_send_reset(). --ANK
563 */
564
565 if (skb->protocol == htons(ETH_P_IP))
566 return dccp_v4_do_rcv(sk, skb);
567
fda9ef5d 568 if (sk_filter(sk, skb))
3df80d93
ACM
569 goto discard;
570
571 /*
45329e71
ACM
572 * socket locking is here for SMP purposes as backlog rcv is currently
573 * called with bh processing disabled.
3df80d93
ACM
574 */
575
576 /* Do Stevens' IPV6_PKTOPTIONS.
577
578 Yes, guys, it is the only place in our code, where we
579 may make it not affecting IPv4.
580 The rest of code is protocol independent,
581 and I do not like idea to uglify IPv4.
582
583 Actually, all the idea behind IPV6_PKTOPTIONS
584 looks not very well thought. For now we latch
585 options, received in the last packet, enqueued
586 by tcp. Feel free to propose better solution.
c9eaf173 587 --ANK (980728)
3df80d93
ACM
588 */
589 if (np->rxopt.all)
89e7e577
GR
590 /*
591 * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below
592 * (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example.
593 */
3df80d93
ACM
594 opt_skb = skb_clone(skb, GFP_ATOMIC);
595
596 if (sk->sk_state == DCCP_OPEN) { /* Fast path */
597 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
598 goto reset;
fd169f15 599 if (opt_skb) {
89e7e577 600 /* XXX This is where we would goto ipv6_pktoptions. */
fd169f15
DM
601 __kfree_skb(opt_skb);
602 }
3df80d93
ACM
603 return 0;
604 }
605
d83ca5ac
GR
606 /*
607 * Step 3: Process LISTEN state
608 * If S.state == LISTEN,
609 * If P.type == Request or P contains a valid Init Cookie option,
610 * (* Must scan the packet's options to check for Init
611 * Cookies. Only Init Cookies are processed here,
612 * however; other options are processed in Step 8. This
613 * scan need only be performed if the endpoint uses Init
614 * Cookies *)
615 * (* Generate a new socket and switch to that socket *)
616 * Set S := new socket for this port pair
617 * S.state = RESPOND
618 * Choose S.ISS (initial seqno) or set from Init Cookies
619 * Initialize S.GAR := S.ISS
620 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
621 * Continue with S.state == RESPOND
622 * (* A Response packet will be generated in Step 11 *)
623 * Otherwise,
624 * Generate Reset(No Connection) unless P.type == Reset
625 * Drop packet and return
626 *
627 * NOTE: the check for the packet types is done in
628 * dccp_rcv_state_process
629 */
3df80d93
ACM
630
631 if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
632 goto reset;
fd169f15 633 if (opt_skb) {
89e7e577 634 /* XXX This is where we would goto ipv6_pktoptions. */
fd169f15
DM
635 __kfree_skb(opt_skb);
636 }
3df80d93
ACM
637 return 0;
638
639reset:
cfb6eeb4 640 dccp_v6_ctl_send_reset(sk, skb);
3df80d93 641discard:
45329e71 642 if (opt_skb != NULL)
3df80d93
ACM
643 __kfree_skb(opt_skb);
644 kfree_skb(skb);
645 return 0;
646}
647
e5bbef20 648static int dccp_v6_rcv(struct sk_buff *skb)
3df80d93
ACM
649{
650 const struct dccp_hdr *dh;
3b24d854 651 bool refcounted;
3df80d93 652 struct sock *sk;
6f4e5fff 653 int min_cov;
3df80d93 654
6f4e5fff 655 /* Step 1: Check header basics */
3df80d93
ACM
656
657 if (dccp_invalid_packet(skb))
658 goto discard_it;
659
6f4e5fff 660 /* Step 1: If header checksum is incorrect, drop packet and return. */
0660e03f
ACM
661 if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->saddr,
662 &ipv6_hdr(skb)->daddr)) {
59348b19 663 DCCP_WARN("dropped packet with invalid checksum\n");
6f4e5fff
GR
664 goto discard_it;
665 }
666
3df80d93
ACM
667 dh = dccp_hdr(skb);
668
fde20105 669 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh);
3df80d93
ACM
670 DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
671
672 if (dccp_packet_without_ack(skb))
673 DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
674 else
675 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
676
4bdc3d66 677lookup:
a583636a 678 sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
870c3151 679 dh->dccph_sport, dh->dccph_dport,
3b24d854 680 inet6_iif(skb), &refcounted);
4bdc3d66 681 if (!sk) {
d23c7107
GR
682 dccp_pr_debug("failed to look up flow ID in table and "
683 "get corresponding socket\n");
3df80d93 684 goto no_dccp_socket;
d23c7107 685 }
3df80d93 686
45329e71 687 /*
3df80d93 688 * Step 2:
8109b02b 689 * ... or S.state == TIMEWAIT,
3df80d93
ACM
690 * Generate Reset(No Connection) unless P.type == Reset
691 * Drop packet and return
692 */
d23c7107
GR
693 if (sk->sk_state == DCCP_TIME_WAIT) {
694 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
695 inet_twsk_put(inet_twsk(sk));
696 goto no_dccp_socket;
697 }
3df80d93 698
079096f1
ED
699 if (sk->sk_state == DCCP_NEW_SYN_RECV) {
700 struct request_sock *req = inet_reqsk(sk);
7716682c 701 struct sock *nsk;
079096f1
ED
702
703 sk = req->rsk_listener;
7716682c 704 if (unlikely(sk->sk_state != DCCP_LISTEN)) {
f03f2e15 705 inet_csk_reqsk_queue_drop_and_put(sk, req);
4bdc3d66
ED
706 goto lookup;
707 }
7716682c 708 sock_hold(sk);
3b24d854 709 refcounted = true;
7716682c 710 nsk = dccp_check_req(sk, skb, req);
079096f1
ED
711 if (!nsk) {
712 reqsk_put(req);
7716682c 713 goto discard_and_relse;
079096f1
ED
714 }
715 if (nsk == sk) {
079096f1
ED
716 reqsk_put(req);
717 } else if (dccp_child_process(sk, nsk, skb)) {
718 dccp_v6_ctl_send_reset(sk, skb);
7716682c 719 goto discard_and_relse;
079096f1 720 } else {
7716682c 721 sock_put(sk);
079096f1
ED
722 return 0;
723 }
724 }
6f4e5fff
GR
725 /*
726 * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
8109b02b
ACM
727 * o if MinCsCov = 0, only packets with CsCov = 0 are accepted
728 * o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
6f4e5fff
GR
729 */
730 min_cov = dccp_sk(sk)->dccps_pcrlen;
731 if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov)) {
732 dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
733 dh->dccph_cscov, min_cov);
734 /* FIXME: send Data Dropped option (see also dccp_v4_rcv) */
735 goto discard_and_relse;
736 }
737
3df80d93
ACM
738 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
739 goto discard_and_relse;
740
4f0c40d9 741 return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4) ? -1 : 0;
3df80d93
ACM
742
743no_dccp_socket:
744 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
745 goto discard_it;
746 /*
747 * Step 2:
8109b02b 748 * If no socket ...
3df80d93
ACM
749 * Generate Reset(No Connection) unless P.type == Reset
750 * Drop packet and return
751 */
752 if (dh->dccph_type != DCCP_PKT_RESET) {
753 DCCP_SKB_CB(skb)->dccpd_reset_code =
754 DCCP_RESET_CODE_NO_CONNECTION;
cfb6eeb4 755 dccp_v6_ctl_send_reset(sk, skb);
3df80d93 756 }
3df80d93 757
d23c7107 758discard_it:
3df80d93
ACM
759 kfree_skb(skb);
760 return 0;
761
762discard_and_relse:
3b24d854
ED
763 if (refcounted)
764 sock_put(sk);
3df80d93 765 goto discard_it;
3df80d93
ACM
766}
767
73c9e02c
GR
768static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
769 int addr_len)
770{
771 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
772 struct inet_connection_sock *icsk = inet_csk(sk);
773 struct inet_sock *inet = inet_sk(sk);
774 struct ipv6_pinfo *np = inet6_sk(sk);
775 struct dccp_sock *dp = dccp_sk(sk);
20c59de2 776 struct in6_addr *saddr = NULL, *final_p, final;
45f6fad8 777 struct ipv6_txoptions *opt;
4c9483b2 778 struct flowi6 fl6;
73c9e02c
GR
779 struct dst_entry *dst;
780 int addr_type;
781 int err;
782
783 dp->dccps_role = DCCP_ROLE_CLIENT;
784
785 if (addr_len < SIN6_LEN_RFC2133)
786 return -EINVAL;
787
788 if (usin->sin6_family != AF_INET6)
789 return -EAFNOSUPPORT;
790
4c9483b2 791 memset(&fl6, 0, sizeof(fl6));
73c9e02c
GR
792
793 if (np->sndflow) {
4c9483b2
DM
794 fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
795 IP6_ECN_flow_init(fl6.flowlabel);
796 if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) {
73c9e02c 797 struct ip6_flowlabel *flowlabel;
4c9483b2 798 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
73c9e02c
GR
799 if (flowlabel == NULL)
800 return -EINVAL;
73c9e02c
GR
801 fl6_sock_release(flowlabel);
802 }
803 }
804 /*
805 * connect() to INADDR_ANY means loopback (BSD'ism).
806 */
807 if (ipv6_addr_any(&usin->sin6_addr))
808 usin->sin6_addr.s6_addr[15] = 1;
809
810 addr_type = ipv6_addr_type(&usin->sin6_addr);
811
812 if (addr_type & IPV6_ADDR_MULTICAST)
813 return -ENETUNREACH;
814
815 if (addr_type & IPV6_ADDR_LINKLOCAL) {
816 if (addr_len >= sizeof(struct sockaddr_in6) &&
817 usin->sin6_scope_id) {
818 /* If interface is set while binding, indices
819 * must coincide.
820 */
821 if (sk->sk_bound_dev_if &&
822 sk->sk_bound_dev_if != usin->sin6_scope_id)
823 return -EINVAL;
824
825 sk->sk_bound_dev_if = usin->sin6_scope_id;
826 }
827
828 /* Connect to link-local address requires an interface */
829 if (!sk->sk_bound_dev_if)
830 return -EINVAL;
831 }
832
efe4208f 833 sk->sk_v6_daddr = usin->sin6_addr;
4c9483b2 834 np->flow_label = fl6.flowlabel;
73c9e02c
GR
835
836 /*
837 * DCCP over IPv4
838 */
839 if (addr_type == IPV6_ADDR_MAPPED) {
840 u32 exthdrlen = icsk->icsk_ext_hdr_len;
841 struct sockaddr_in sin;
842
843 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
844
845 if (__ipv6_only_sock(sk))
846 return -ENETUNREACH;
847
848 sin.sin_family = AF_INET;
849 sin.sin_port = usin->sin6_port;
850 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
851
852 icsk->icsk_af_ops = &dccp_ipv6_mapped;
853 sk->sk_backlog_rcv = dccp_v4_do_rcv;
854
855 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
856 if (err) {
857 icsk->icsk_ext_hdr_len = exthdrlen;
858 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
859 sk->sk_backlog_rcv = dccp_v6_do_rcv;
860 goto failure;
73c9e02c 861 }
d1e559d0 862 np->saddr = sk->sk_v6_rcv_saddr;
73c9e02c
GR
863 return err;
864 }
865
efe4208f
ED
866 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr))
867 saddr = &sk->sk_v6_rcv_saddr;
73c9e02c 868
4c9483b2 869 fl6.flowi6_proto = IPPROTO_DCCP;
efe4208f 870 fl6.daddr = sk->sk_v6_daddr;
4e3fd7a0 871 fl6.saddr = saddr ? *saddr : np->saddr;
4c9483b2 872 fl6.flowi6_oif = sk->sk_bound_dev_if;
1958b856
DM
873 fl6.fl6_dport = usin->sin6_port;
874 fl6.fl6_sport = inet->inet_sport;
4c9483b2 875 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
73c9e02c 876
1e1d04e6 877 opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
45f6fad8 878 final_p = fl6_update_dst(&fl6, opt, &final);
73c9e02c 879
0e0d44ab 880 dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
68d0c6d3
DM
881 if (IS_ERR(dst)) {
882 err = PTR_ERR(dst);
73c9e02c 883 goto failure;
14e50e57 884 }
73c9e02c
GR
885
886 if (saddr == NULL) {
4c9483b2 887 saddr = &fl6.saddr;
efe4208f 888 sk->sk_v6_rcv_saddr = *saddr;
73c9e02c
GR
889 }
890
891 /* set the source address */
4e3fd7a0 892 np->saddr = *saddr;
c720c7e8 893 inet->inet_rcv_saddr = LOOPBACK4_IPV6;
73c9e02c 894
6bd4f355 895 ip6_dst_store(sk, dst, NULL, NULL);
73c9e02c
GR
896
897 icsk->icsk_ext_hdr_len = 0;
45f6fad8
ED
898 if (opt)
899 icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
73c9e02c 900
c720c7e8 901 inet->inet_dport = usin->sin6_port;
73c9e02c
GR
902
903 dccp_set_state(sk, DCCP_REQUESTING);
904 err = inet6_hash_connect(&dccp_death_row, sk);
905 if (err)
906 goto late_failure;
d7f7365f
GR
907
908 dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
efe4208f 909 sk->sk_v6_daddr.s6_addr32,
c720c7e8
ED
910 inet->inet_sport,
911 inet->inet_dport);
73c9e02c
GR
912 err = dccp_connect(sk);
913 if (err)
914 goto late_failure;
915
916 return 0;
917
918late_failure:
919 dccp_set_state(sk, DCCP_CLOSED);
920 __sk_dst_reset(sk);
921failure:
c720c7e8 922 inet->inet_dport = 0;
73c9e02c
GR
923 sk->sk_route_caps = 0;
924 return err;
925}
926
3b401a81 927static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
543d9cfe
ACM
928 .queue_xmit = inet6_csk_xmit,
929 .send_check = dccp_v6_send_check,
930 .rebuild_header = inet6_sk_rebuild_header,
931 .conn_request = dccp_v6_conn_request,
932 .syn_recv_sock = dccp_v6_request_recv_sock,
933 .net_header_len = sizeof(struct ipv6hdr),
934 .setsockopt = ipv6_setsockopt,
935 .getsockopt = ipv6_getsockopt,
936 .addr2sockaddr = inet6_csk_addr2sockaddr,
937 .sockaddr_len = sizeof(struct sockaddr_in6),
ab1e0a13 938 .bind_conflict = inet6_csk_bind_conflict,
3fdadf7d 939#ifdef CONFIG_COMPAT
543d9cfe
ACM
940 .compat_setsockopt = compat_ipv6_setsockopt,
941 .compat_getsockopt = compat_ipv6_getsockopt,
3fdadf7d 942#endif
3df80d93
ACM
943};
944
945/*
946 * DCCP over IPv4 via INET6 API
947 */
3b401a81 948static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
543d9cfe
ACM
949 .queue_xmit = ip_queue_xmit,
950 .send_check = dccp_v4_send_check,
951 .rebuild_header = inet_sk_rebuild_header,
952 .conn_request = dccp_v6_conn_request,
953 .syn_recv_sock = dccp_v6_request_recv_sock,
954 .net_header_len = sizeof(struct iphdr),
955 .setsockopt = ipv6_setsockopt,
956 .getsockopt = ipv6_getsockopt,
957 .addr2sockaddr = inet6_csk_addr2sockaddr,
958 .sockaddr_len = sizeof(struct sockaddr_in6),
3fdadf7d 959#ifdef CONFIG_COMPAT
543d9cfe
ACM
960 .compat_setsockopt = compat_ipv6_setsockopt,
961 .compat_getsockopt = compat_ipv6_getsockopt,
3fdadf7d 962#endif
3df80d93
ACM
963};
964
965/* NOTE: A lot of things set to zero explicitly by call to
966 * sk_alloc() so need not be done here.
967 */
968static int dccp_v6_init_sock(struct sock *sk)
969{
72478873
ACM
970 static __u8 dccp_v6_ctl_sock_initialized;
971 int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
3df80d93 972
72478873
ACM
973 if (err == 0) {
974 if (unlikely(!dccp_v6_ctl_sock_initialized))
975 dccp_v6_ctl_sock_initialized = 1;
3df80d93 976 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
72478873 977 }
3df80d93
ACM
978
979 return err;
980}
981
7d06b2e0 982static void dccp_v6_destroy_sock(struct sock *sk)
3df80d93 983{
3e0fadc5 984 dccp_destroy_sock(sk);
7d06b2e0 985 inet6_destroy_sock(sk);
3df80d93
ACM
986}
987
73c9e02c
GR
988static struct timewait_sock_ops dccp6_timewait_sock_ops = {
989 .twsk_obj_size = sizeof(struct dccp6_timewait_sock),
990};
991
3df80d93 992static struct proto dccp_v6_prot = {
543d9cfe
ACM
993 .name = "DCCPv6",
994 .owner = THIS_MODULE,
995 .close = dccp_close,
996 .connect = dccp_v6_connect,
997 .disconnect = dccp_disconnect,
998 .ioctl = dccp_ioctl,
999 .init = dccp_v6_init_sock,
1000 .setsockopt = dccp_setsockopt,
1001 .getsockopt = dccp_getsockopt,
1002 .sendmsg = dccp_sendmsg,
1003 .recvmsg = dccp_recvmsg,
1004 .backlog_rcv = dccp_v6_do_rcv,
496611d7 1005 .hash = inet6_hash,
ab1e0a13 1006 .unhash = inet_unhash,
543d9cfe 1007 .accept = inet_csk_accept,
ab1e0a13 1008 .get_port = inet_csk_get_port,
543d9cfe
ACM
1009 .shutdown = dccp_shutdown,
1010 .destroy = dccp_v6_destroy_sock,
1011 .orphan_count = &dccp_orphan_count,
1012 .max_header = MAX_DCCP_HEADER,
1013 .obj_size = sizeof(struct dccp6_sock),
3ab5aee7 1014 .slab_flags = SLAB_DESTROY_BY_RCU,
543d9cfe
ACM
1015 .rsk_prot = &dccp6_request_sock_ops,
1016 .twsk_prot = &dccp6_timewait_sock_ops,
39d8cda7 1017 .h.hashinfo = &dccp_hashinfo,
3fdadf7d 1018#ifdef CONFIG_COMPAT
543d9cfe
ACM
1019 .compat_setsockopt = compat_dccp_setsockopt,
1020 .compat_getsockopt = compat_dccp_getsockopt,
3fdadf7d 1021#endif
3df80d93
ACM
1022};
1023
41135cc8 1024static const struct inet6_protocol dccp_v6_protocol = {
45329e71
ACM
1025 .handler = dccp_v6_rcv,
1026 .err_handler = dccp_v6_err,
1027 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
3df80d93
ACM
1028};
1029
5708e868 1030static const struct proto_ops inet6_dccp_ops = {
543d9cfe
ACM
1031 .family = PF_INET6,
1032 .owner = THIS_MODULE,
1033 .release = inet6_release,
1034 .bind = inet6_bind,
1035 .connect = inet_stream_connect,
1036 .socketpair = sock_no_socketpair,
1037 .accept = inet_accept,
1038 .getname = inet6_getname,
1039 .poll = dccp_poll,
1040 .ioctl = inet6_ioctl,
1041 .listen = inet_dccp_listen,
1042 .shutdown = inet_shutdown,
1043 .setsockopt = sock_common_setsockopt,
1044 .getsockopt = sock_common_getsockopt,
1045 .sendmsg = inet_sendmsg,
1046 .recvmsg = sock_common_recvmsg,
1047 .mmap = sock_no_mmap,
1048 .sendpage = sock_no_sendpage,
3fdadf7d 1049#ifdef CONFIG_COMPAT
543d9cfe
ACM
1050 .compat_setsockopt = compat_sock_common_setsockopt,
1051 .compat_getsockopt = compat_sock_common_getsockopt,
3fdadf7d 1052#endif
3df80d93
ACM
1053};
1054
1055static struct inet_protosw dccp_v6_protosw = {
1056 .type = SOCK_DCCP,
1057 .protocol = IPPROTO_DCCP,
1058 .prot = &dccp_v6_prot,
1059 .ops = &inet6_dccp_ops,
d83d8461 1060 .flags = INET_PROTOSW_ICSK,
3df80d93
ACM
1061};
1062
2c8c1e72 1063static int __net_init dccp_v6_init_net(struct net *net)
8231bd27 1064{
d14a0ebd
GR
1065 if (dccp_hashinfo.bhash == NULL)
1066 return -ESOCKTNOSUPPORT;
334527d3 1067
d14a0ebd
GR
1068 return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
1069 SOCK_DCCP, IPPROTO_DCCP, net);
8231bd27
PE
1070}
1071
2c8c1e72 1072static void __net_exit dccp_v6_exit_net(struct net *net)
8231bd27 1073{
334527d3 1074 inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
8231bd27
PE
1075}
1076
1077static struct pernet_operations dccp_v6_ops = {
1078 .init = dccp_v6_init_net,
1079 .exit = dccp_v6_exit_net,
1080};
1081
3df80d93
ACM
1082static int __init dccp_v6_init(void)
1083{
1084 int err = proto_register(&dccp_v6_prot, 1);
1085
1086 if (err != 0)
1087 goto out;
1088
1089 err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1090 if (err != 0)
1091 goto out_unregister_proto;
1092
1093 inet6_register_protosw(&dccp_v6_protosw);
72478873 1094
8231bd27
PE
1095 err = register_pernet_subsys(&dccp_v6_ops);
1096 if (err != 0)
1097 goto out_destroy_ctl_sock;
3df80d93
ACM
1098out:
1099 return err;
8231bd27
PE
1100
1101out_destroy_ctl_sock:
72478873
ACM
1102 inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1103 inet6_unregister_protosw(&dccp_v6_protosw);
3df80d93
ACM
1104out_unregister_proto:
1105 proto_unregister(&dccp_v6_prot);
1106 goto out;
1107}
1108
1109static void __exit dccp_v6_exit(void)
1110{
8231bd27 1111 unregister_pernet_subsys(&dccp_v6_ops);
3df80d93
ACM
1112 inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1113 inet6_unregister_protosw(&dccp_v6_protosw);
1114 proto_unregister(&dccp_v6_prot);
1115}
1116
1117module_init(dccp_v6_init);
1118module_exit(dccp_v6_exit);
1119
1120/*
1121 * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
1122 * values directly, Also cover the case where the protocol is not specified,
1123 * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
1124 */
7131c6c7
JD
1125MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
1126MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
3df80d93
ACM
1127MODULE_LICENSE("GPL");
1128MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
1129MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");