aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r--net/dccp/ipv6.c371
1 files changed, 196 insertions, 175 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 80c4d048869e..65e2ab0886e6 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * DCCP over IPv6 2 * DCCP over IPv6
3 * Linux INET6 implementation 3 * Linux INET6 implementation
4 * 4 *
5 * Based on net/dccp6/ipv6.c 5 * Based on net/dccp6/ipv6.c
6 * 6 *
@@ -33,6 +33,9 @@
33#include "dccp.h" 33#include "dccp.h"
34#include "ipv6.h" 34#include "ipv6.h"
35 35
36/* Socket used for sending RSTs and ACKs */
37static struct socket *dccp_v6_ctl_socket;
38
36static void dccp_v6_ctl_send_reset(struct sk_buff *skb); 39static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
37static void dccp_v6_reqsk_send_ack(struct sk_buff *skb, 40static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
38 struct request_sock *req); 41 struct request_sock *req);
@@ -53,7 +56,7 @@ static void dccp_v6_hash(struct sock *sk)
53{ 56{
54 if (sk->sk_state != DCCP_CLOSED) { 57 if (sk->sk_state != DCCP_CLOSED) {
55 if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) { 58 if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
56 dccp_prot.hash(sk); 59 dccp_hash(sk);
57 return; 60 return;
58 } 61 }
59 local_bh_disable(); 62 local_bh_disable();
@@ -63,8 +66,8 @@ static void dccp_v6_hash(struct sock *sk)
63} 66}
64 67
65static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len, 68static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len,
66 struct in6_addr *saddr, 69 struct in6_addr *saddr,
67 struct in6_addr *daddr, 70 struct in6_addr *daddr,
68 unsigned long base) 71 unsigned long base)
69{ 72{
70 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base); 73 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base);
@@ -79,17 +82,17 @@ static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
79 skb->nh.ipv6h->saddr.s6_addr32, 82 skb->nh.ipv6h->saddr.s6_addr32,
80 dh->dccph_dport, 83 dh->dccph_dport,
81 dh->dccph_sport); 84 dh->dccph_sport);
82 else 85
83 return secure_dccp_sequence_number(skb->nh.iph->daddr, 86 return secure_dccp_sequence_number(skb->nh.iph->daddr,
84 skb->nh.iph->saddr, 87 skb->nh.iph->saddr,
85 dh->dccph_dport, 88 dh->dccph_dport,
86 dh->dccph_sport); 89 dh->dccph_sport);
87} 90}
88 91
89static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 92static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
90 int addr_len) 93 int addr_len)
91{ 94{
92 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 95 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
93 struct inet_connection_sock *icsk = inet_csk(sk); 96 struct inet_connection_sock *icsk = inet_csk(sk);
94 struct inet_sock *inet = inet_sk(sk); 97 struct inet_sock *inet = inet_sk(sk);
95 struct ipv6_pinfo *np = inet6_sk(sk); 98 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -102,10 +105,10 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
102 105
103 dp->dccps_role = DCCP_ROLE_CLIENT; 106 dp->dccps_role = DCCP_ROLE_CLIENT;
104 107
105 if (addr_len < SIN6_LEN_RFC2133) 108 if (addr_len < SIN6_LEN_RFC2133)
106 return -EINVAL; 109 return -EINVAL;
107 110
108 if (usin->sin6_family != AF_INET6) 111 if (usin->sin6_family != AF_INET6)
109 return -EAFNOSUPPORT; 112 return -EAFNOSUPPORT;
110 113
111 memset(&fl, 0, sizeof(fl)); 114 memset(&fl, 0, sizeof(fl));
@@ -122,17 +125,15 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
122 fl6_sock_release(flowlabel); 125 fl6_sock_release(flowlabel);
123 } 126 }
124 } 127 }
125
126 /* 128 /*
127 * connect() to INADDR_ANY means loopback (BSD'ism). 129 * connect() to INADDR_ANY means loopback (BSD'ism).
128 */ 130 */
129 131 if (ipv6_addr_any(&usin->sin6_addr))
130 if (ipv6_addr_any(&usin->sin6_addr)) 132 usin->sin6_addr.s6_addr[15] = 1;
131 usin->sin6_addr.s6_addr[15] = 0x1;
132 133
133 addr_type = ipv6_addr_type(&usin->sin6_addr); 134 addr_type = ipv6_addr_type(&usin->sin6_addr);
134 135
135 if(addr_type & IPV6_ADDR_MULTICAST) 136 if (addr_type & IPV6_ADDR_MULTICAST)
136 return -ENETUNREACH; 137 return -ENETUNREACH;
137 138
138 if (addr_type & IPV6_ADDR_LINKLOCAL) { 139 if (addr_type & IPV6_ADDR_LINKLOCAL) {
@@ -157,9 +158,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
157 np->flow_label = fl.fl6_flowlabel; 158 np->flow_label = fl.fl6_flowlabel;
158 159
159 /* 160 /*
160 * DCCP over IPv4 161 * DCCP over IPv4
161 */ 162 */
162
163 if (addr_type == IPV6_ADDR_MAPPED) { 163 if (addr_type == IPV6_ADDR_MAPPED) {
164 u32 exthdrlen = icsk->icsk_ext_hdr_len; 164 u32 exthdrlen = icsk->icsk_ext_hdr_len;
165 struct sockaddr_in sin; 165 struct sockaddr_in sin;
@@ -177,7 +177,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
177 sk->sk_backlog_rcv = dccp_v4_do_rcv; 177 sk->sk_backlog_rcv = dccp_v4_do_rcv;
178 178
179 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); 179 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
180
181 if (err) { 180 if (err) {
182 icsk->icsk_ext_hdr_len = exthdrlen; 181 icsk->icsk_ext_hdr_len = exthdrlen;
183 icsk->icsk_af_ops = &dccp_ipv6_af_ops; 182 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
@@ -203,8 +202,9 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
203 fl.fl_ip_dport = usin->sin6_port; 202 fl.fl_ip_dport = usin->sin6_port;
204 fl.fl_ip_sport = inet->sport; 203 fl.fl_ip_sport = inet->sport;
205 204
206 if (np->opt && np->opt->srcrt) { 205 if (np->opt != NULL && np->opt->srcrt != NULL) {
207 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; 206 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
207
208 ipv6_addr_copy(&final, &fl.fl6_dst); 208 ipv6_addr_copy(&final, &fl.fl6_dst);
209 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); 209 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
210 final_p = &final; 210 final_p = &final;
@@ -213,10 +213,12 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
213 err = ip6_dst_lookup(sk, &dst, &fl); 213 err = ip6_dst_lookup(sk, &dst, &fl);
214 if (err) 214 if (err)
215 goto failure; 215 goto failure;
216
216 if (final_p) 217 if (final_p)
217 ipv6_addr_copy(&fl.fl6_dst, final_p); 218 ipv6_addr_copy(&fl.fl6_dst, final_p);
218 219
219 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 220 err = xfrm_lookup(&dst, &fl, sk, 0);
221 if (err < 0)
220 goto failure; 222 goto failure;
221 223
222 if (saddr == NULL) { 224 if (saddr == NULL) {
@@ -231,7 +233,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
231 ip6_dst_store(sk, dst, NULL); 233 ip6_dst_store(sk, dst, NULL);
232 234
233 icsk->icsk_ext_hdr_len = 0; 235 icsk->icsk_ext_hdr_len = 0;
234 if (np->opt) 236 if (np->opt != NULL)
235 icsk->icsk_ext_hdr_len = (np->opt->opt_flen + 237 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
236 np->opt->opt_nflen); 238 np->opt->opt_nflen);
237 239
@@ -264,7 +266,7 @@ failure:
264} 266}
265 267
266static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 268static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
267 int type, int code, int offset, __u32 info) 269 int type, int code, int offset, __be32 info)
268{ 270{
269 struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data; 271 struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
270 const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); 272 const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
@@ -305,7 +307,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
305 307
306 /* icmp should have updated the destination cache entry */ 308 /* icmp should have updated the destination cache entry */
307 dst = __sk_dst_check(sk, np->dst_cookie); 309 dst = __sk_dst_check(sk, np->dst_cookie);
308
309 if (dst == NULL) { 310 if (dst == NULL) {
310 struct inet_sock *inet = inet_sk(sk); 311 struct inet_sock *inet = inet_sk(sk);
311 struct flowi fl; 312 struct flowi fl;
@@ -322,16 +323,17 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
322 fl.fl_ip_dport = inet->dport; 323 fl.fl_ip_dport = inet->dport;
323 fl.fl_ip_sport = inet->sport; 324 fl.fl_ip_sport = inet->sport;
324 325
325 if ((err = ip6_dst_lookup(sk, &dst, &fl))) { 326 err = ip6_dst_lookup(sk, &dst, &fl);
327 if (err) {
326 sk->sk_err_soft = -err; 328 sk->sk_err_soft = -err;
327 goto out; 329 goto out;
328 } 330 }
329 331
330 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 332 err = xfrm_lookup(&dst, &fl, sk, 0);
333 if (err < 0) {
331 sk->sk_err_soft = -err; 334 sk->sk_err_soft = -err;
332 goto out; 335 goto out;
333 } 336 }
334
335 } else 337 } else
336 dst_hold(dst); 338 dst_hold(dst);
337 339
@@ -355,11 +357,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
355 req = inet6_csk_search_req(sk, &prev, dh->dccph_dport, 357 req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
356 &hdr->daddr, &hdr->saddr, 358 &hdr->daddr, &hdr->saddr,
357 inet6_iif(skb)); 359 inet6_iif(skb));
358 if (!req) 360 if (req == NULL)
359 goto out; 361 goto out;
360 362
361 /* ICMPs are not backlogged, hence we cannot get 363 /*
362 * an established socket here. 364 * ICMPs are not backlogged, hence we cannot get an established
365 * socket here.
363 */ 366 */
364 BUG_TRAP(req->sk == NULL); 367 BUG_TRAP(req->sk == NULL);
365 368
@@ -373,7 +376,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
373 376
374 case DCCP_REQUESTING: 377 case DCCP_REQUESTING:
375 case DCCP_RESPOND: /* Cannot happen. 378 case DCCP_RESPOND: /* Cannot happen.
376 It can, it SYNs are crossed. --ANK */ 379 It can, it SYNs are crossed. --ANK */
377 if (!sock_owned_by_user(sk)) { 380 if (!sock_owned_by_user(sk)) {
378 DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); 381 DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
379 sk->sk_err = err; 382 sk->sk_err = err;
@@ -382,7 +385,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
382 * (see connect in sock.c) 385 * (see connect in sock.c)
383 */ 386 */
384 sk->sk_error_report(sk); 387 sk->sk_error_report(sk);
385
386 dccp_done(sk); 388 dccp_done(sk);
387 } else 389 } else
388 sk->sk_err_soft = err; 390 sk->sk_err_soft = err;
@@ -428,14 +430,16 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
428 ireq6->pktopts) { 430 ireq6->pktopts) {
429 struct sk_buff *pktopts = ireq6->pktopts; 431 struct sk_buff *pktopts = ireq6->pktopts;
430 struct inet6_skb_parm *rxopt = IP6CB(pktopts); 432 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
433
431 if (rxopt->srcrt) 434 if (rxopt->srcrt)
432 opt = ipv6_invert_rthdr(sk, 435 opt = ipv6_invert_rthdr(sk,
433 (struct ipv6_rt_hdr *)(pktopts->nh.raw + 436 (struct ipv6_rt_hdr *)(pktopts->nh.raw +
434 rxopt->srcrt)); 437 rxopt->srcrt));
435 } 438 }
436 439
437 if (opt && opt->srcrt) { 440 if (opt != NULL && opt->srcrt != NULL) {
438 struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; 441 const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
442
439 ipv6_addr_copy(&final, &fl.fl6_dst); 443 ipv6_addr_copy(&final, &fl.fl6_dst);
440 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); 444 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
441 final_p = &final; 445 final_p = &final;
@@ -444,15 +448,19 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
444 err = ip6_dst_lookup(sk, &dst, &fl); 448 err = ip6_dst_lookup(sk, &dst, &fl);
445 if (err) 449 if (err)
446 goto done; 450 goto done;
451
447 if (final_p) 452 if (final_p)
448 ipv6_addr_copy(&fl.fl6_dst, final_p); 453 ipv6_addr_copy(&fl.fl6_dst, final_p);
449 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 454
455 err = xfrm_lookup(&dst, &fl, sk, 0);
456 if (err < 0)
450 goto done; 457 goto done;
451 } 458 }
452 459
453 skb = dccp_make_response(sk, dst, req); 460 skb = dccp_make_response(sk, dst, req);
454 if (skb != NULL) { 461 if (skb != NULL) {
455 struct dccp_hdr *dh = dccp_hdr(skb); 462 struct dccp_hdr *dh = dccp_hdr(skb);
463
456 dh->dccph_checksum = dccp_v6_check(dh, skb->len, 464 dh->dccph_checksum = dccp_v6_check(dh, skb->len,
457 &ireq6->loc_addr, 465 &ireq6->loc_addr,
458 &ireq6->rmt_addr, 466 &ireq6->rmt_addr,
@@ -466,7 +474,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
466 } 474 }
467 475
468done: 476done:
469 if (opt && opt != np->opt) 477 if (opt != NULL && opt != np->opt)
470 sock_kfree_s(sk, opt, opt->tot_len); 478 sock_kfree_s(sk, opt, opt->tot_len);
471 dst_release(dst); 479 dst_release(dst);
472 return err; 480 return err;
@@ -497,7 +505,7 @@ static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
497 struct dccp_hdr *dh = dccp_hdr(skb); 505 struct dccp_hdr *dh = dccp_hdr(skb);
498 506
499 dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr, 507 dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
500 len, IPPROTO_DCCP, 508 len, IPPROTO_DCCP,
501 csum_partial((char *)dh, 509 csum_partial((char *)dh,
502 dh->dccph_doff << 2, 510 dh->dccph_doff << 2,
503 skb->csum)); 511 skb->csum));
@@ -505,8 +513,8 @@ static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
505 513
506static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) 514static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
507{ 515{
508 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 516 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
509 const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) + 517 const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
510 sizeof(struct dccp_hdr_ext) + 518 sizeof(struct dccp_hdr_ext) +
511 sizeof(struct dccp_hdr_reset); 519 sizeof(struct dccp_hdr_reset);
512 struct sk_buff *skb; 520 struct sk_buff *skb;
@@ -517,20 +525,14 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
517 return; 525 return;
518 526
519 if (!ipv6_unicast_destination(rxskb)) 527 if (!ipv6_unicast_destination(rxskb))
520 return; 528 return;
521
522 /*
523 * We need to grab some memory, and put together an RST,
524 * and then put it into the queue to be sent.
525 */
526 529
527 skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + 530 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
528 dccp_hdr_reset_len, GFP_ATOMIC); 531 GFP_ATOMIC);
529 if (skb == NULL) 532 if (skb == NULL)
530 return; 533 return;
531 534
532 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) + 535 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
533 dccp_hdr_reset_len);
534 536
535 skb->h.raw = skb_push(skb, dccp_hdr_reset_len); 537 skb->h.raw = skb_push(skb, dccp_hdr_reset_len);
536 dh = dccp_hdr(skb); 538 dh = dccp_hdr(skb);
@@ -568,7 +570,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
568 /* sk = NULL, but it is safe for now. RST socket required. */ 570 /* sk = NULL, but it is safe for now. RST socket required. */
569 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { 571 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
570 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { 572 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
571 ip6_xmit(NULL, skb, &fl, NULL, 0); 573 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
572 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 574 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
573 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); 575 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
574 return; 576 return;
@@ -578,22 +580,22 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
578 kfree_skb(skb); 580 kfree_skb(skb);
579} 581}
580 582
581static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb) 583static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb,
584 struct request_sock *req)
582{ 585{
583 struct flowi fl; 586 struct flowi fl;
584 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 587 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
585 const int dccp_hdr_ack_len = sizeof(struct dccp_hdr) + 588 const u32 dccp_hdr_ack_len = sizeof(struct dccp_hdr) +
586 sizeof(struct dccp_hdr_ext) + 589 sizeof(struct dccp_hdr_ext) +
587 sizeof(struct dccp_hdr_ack_bits); 590 sizeof(struct dccp_hdr_ack_bits);
588 struct sk_buff *skb; 591 struct sk_buff *skb;
589 592
590 skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + 593 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
591 dccp_hdr_ack_len, GFP_ATOMIC); 594 GFP_ATOMIC);
592 if (skb == NULL) 595 if (skb == NULL)
593 return; 596 return;
594 597
595 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) + 598 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
596 dccp_hdr_ack_len);
597 599
598 skb->h.raw = skb_push(skb, dccp_hdr_ack_len); 600 skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
599 dh = dccp_hdr(skb); 601 dh = dccp_hdr(skb);
@@ -605,7 +607,7 @@ static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
605 dh->dccph_dport = rxdh->dccph_sport; 607 dh->dccph_dport = rxdh->dccph_sport;
606 dh->dccph_doff = dccp_hdr_ack_len / 4; 608 dh->dccph_doff = dccp_hdr_ack_len / 4;
607 dh->dccph_x = 1; 609 dh->dccph_x = 1;
608 610
609 dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq); 611 dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
610 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 612 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
611 DCCP_SKB_CB(rxskb)->dccpd_seq); 613 DCCP_SKB_CB(rxskb)->dccpd_seq);
@@ -623,7 +625,7 @@ static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
623 625
624 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { 626 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
625 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { 627 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
626 ip6_xmit(NULL, skb, &fl, NULL, 0); 628 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
627 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 629 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
628 return; 630 return;
629 } 631 }
@@ -632,12 +634,6 @@ static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
632 kfree_skb(skb); 634 kfree_skb(skb);
633} 635}
634 636
635static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
636 struct request_sock *req)
637{
638 dccp_v6_ctl_send_ack(skb);
639}
640
641static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) 637static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
642{ 638{
643 const struct dccp_hdr *dh = dccp_hdr(skb); 639 const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -657,7 +653,6 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
657 &iph->saddr, dh->dccph_sport, 653 &iph->saddr, dh->dccph_sport,
658 &iph->daddr, ntohs(dh->dccph_dport), 654 &iph->daddr, ntohs(dh->dccph_dport),
659 inet6_iif(skb)); 655 inet6_iif(skb));
660
661 if (nsk != NULL) { 656 if (nsk != NULL) {
662 if (nsk->sk_state != DCCP_TIME_WAIT) { 657 if (nsk->sk_state != DCCP_TIME_WAIT) {
663 bh_lock_sock(nsk); 658 bh_lock_sock(nsk);
@@ -678,7 +673,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
678 struct dccp_request_sock *dreq; 673 struct dccp_request_sock *dreq;
679 struct inet6_request_sock *ireq6; 674 struct inet6_request_sock *ireq6;
680 struct ipv6_pinfo *np = inet6_sk(sk); 675 struct ipv6_pinfo *np = inet6_sk(sk);
681 const __u32 service = dccp_hdr_request(skb)->dccph_req_service; 676 const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
682 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 677 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
683 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; 678 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
684 679
@@ -686,17 +681,17 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
686 return dccp_v4_conn_request(sk, skb); 681 return dccp_v4_conn_request(sk, skb);
687 682
688 if (!ipv6_unicast_destination(skb)) 683 if (!ipv6_unicast_destination(skb))
689 goto drop; 684 goto drop;
690 685
691 if (dccp_bad_service_code(sk, service)) { 686 if (dccp_bad_service_code(sk, service)) {
692 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; 687 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
693 goto drop; 688 goto drop;
694 } 689 }
695 /* 690 /*
696 * There are no SYN attacks on IPv6, yet... 691 * There are no SYN attacks on IPv6, yet...
697 */ 692 */
698 if (inet_csk_reqsk_queue_is_full(sk)) 693 if (inet_csk_reqsk_queue_is_full(sk))
699 goto drop; 694 goto drop;
700 695
701 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) 696 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
702 goto drop; 697 goto drop;
@@ -730,7 +725,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
730 ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL) 725 ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
731 ireq6->iif = inet6_iif(skb); 726 ireq6->iif = inet6_iif(skb);
732 727
733 /* 728 /*
734 * Step 3: Process LISTEN state 729 * Step 3: Process LISTEN state
735 * 730 *
736 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 731 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
@@ -774,9 +769,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
774 /* 769 /*
775 * v6 mapped 770 * v6 mapped
776 */ 771 */
777
778 newsk = dccp_v4_request_recv_sock(sk, skb, req, dst); 772 newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
779 if (newsk == NULL) 773 if (newsk == NULL)
780 return NULL; 774 return NULL;
781 775
782 newdp6 = (struct dccp6_sock *)newsk; 776 newdp6 = (struct dccp6_sock *)newsk;
@@ -822,9 +816,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
822 if (sk_acceptq_is_full(sk)) 816 if (sk_acceptq_is_full(sk))
823 goto out_overflow; 817 goto out_overflow;
824 818
825 if (np->rxopt.bits.osrcrt == 2 && 819 if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
826 opt == NULL && ireq6->pktopts) { 820 const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
827 struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts); 821
828 if (rxopt->srcrt) 822 if (rxopt->srcrt)
829 opt = ipv6_invert_rthdr(sk, 823 opt = ipv6_invert_rthdr(sk,
830 (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw + 824 (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
@@ -838,8 +832,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
838 memset(&fl, 0, sizeof(fl)); 832 memset(&fl, 0, sizeof(fl));
839 fl.proto = IPPROTO_DCCP; 833 fl.proto = IPPROTO_DCCP;
840 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); 834 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
841 if (opt && opt->srcrt) { 835 if (opt != NULL && opt->srcrt != NULL) {
842 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; 836 const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
837
843 ipv6_addr_copy(&final, &fl.fl6_dst); 838 ipv6_addr_copy(&final, &fl.fl6_dst);
844 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); 839 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
845 final_p = &final; 840 final_p = &final;
@@ -857,7 +852,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
857 852
858 if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) 853 if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
859 goto out; 854 goto out;
860 } 855 }
861 856
862 newsk = dccp_create_openreq_child(sk, req, skb); 857 newsk = dccp_create_openreq_child(sk, req, skb);
863 if (newsk == NULL) 858 if (newsk == NULL)
@@ -870,9 +865,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
870 */ 865 */
871 866
872 ip6_dst_store(newsk, dst, NULL); 867 ip6_dst_store(newsk, dst, NULL);
873 newsk->sk_route_caps = dst->dev->features & 868 newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
874 ~(NETIF_F_IP_CSUM | NETIF_F_TSO); 869 NETIF_F_TSO);
875
876 newdp6 = (struct dccp6_sock *)newsk; 870 newdp6 = (struct dccp6_sock *)newsk;
877 newinet = inet_sk(newsk); 871 newinet = inet_sk(newsk);
878 newinet->pinet6 = &newdp6->inet6; 872 newinet->pinet6 = &newdp6->inet6;
@@ -886,7 +880,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
886 ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr); 880 ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr);
887 newsk->sk_bound_dev_if = ireq6->iif; 881 newsk->sk_bound_dev_if = ireq6->iif;
888 882
889 /* Now IPv6 options... 883 /* Now IPv6 options...
890 884
891 First: no IPv4 options. 885 First: no IPv4 options.
892 */ 886 */
@@ -908,20 +902,20 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
908 newnp->mcast_oif = inet6_iif(skb); 902 newnp->mcast_oif = inet6_iif(skb);
909 newnp->mcast_hops = skb->nh.ipv6h->hop_limit; 903 newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
910 904
911 /* Clone native IPv6 options from listening socket (if any) 905 /*
912 906 * Clone native IPv6 options from listening socket (if any)
913 Yes, keeping reference count would be much more clever, 907 *
914 but we make one more one thing there: reattach optmem 908 * Yes, keeping reference count would be much more clever, but we make
915 to newsk. 909 * one more one thing there: reattach optmem to newsk.
916 */ 910 */
917 if (opt) { 911 if (opt != NULL) {
918 newnp->opt = ipv6_dup_options(newsk, opt); 912 newnp->opt = ipv6_dup_options(newsk, opt);
919 if (opt != np->opt) 913 if (opt != np->opt)
920 sock_kfree_s(sk, opt, opt->tot_len); 914 sock_kfree_s(sk, opt, opt->tot_len);
921 } 915 }
922 916
923 inet_csk(newsk)->icsk_ext_hdr_len = 0; 917 inet_csk(newsk)->icsk_ext_hdr_len = 0;
924 if (newnp->opt) 918 if (newnp->opt != NULL)
925 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + 919 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
926 newnp->opt->opt_flen); 920 newnp->opt->opt_flen);
927 921
@@ -938,7 +932,7 @@ out_overflow:
938 NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS); 932 NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
939out: 933out:
940 NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS); 934 NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
941 if (opt && opt != np->opt) 935 if (opt != NULL && opt != np->opt)
942 sock_kfree_s(sk, opt, opt->tot_len); 936 sock_kfree_s(sk, opt, opt->tot_len);
943 dst_release(dst); 937 dst_release(dst);
944 return NULL; 938 return NULL;
@@ -972,8 +966,8 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
972 goto discard; 966 goto discard;
973 967
974 /* 968 /*
975 * socket locking is here for SMP purposes as backlog rcv 969 * socket locking is here for SMP purposes as backlog rcv is currently
976 * is currently called with bh processing disabled. 970 * called with bh processing disabled.
977 */ 971 */
978 972
979 /* Do Stevens' IPV6_PKTOPTIONS. 973 /* Do Stevens' IPV6_PKTOPTIONS.
@@ -998,20 +992,20 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
998 return 0; 992 return 0;
999 } 993 }
1000 994
1001 if (sk->sk_state == DCCP_LISTEN) { 995 if (sk->sk_state == DCCP_LISTEN) {
1002 struct sock *nsk = dccp_v6_hnd_req(sk, skb); 996 struct sock *nsk = dccp_v6_hnd_req(sk, skb);
1003 if (!nsk)
1004 goto discard;
1005 997
998 if (nsk == NULL)
999 goto discard;
1006 /* 1000 /*
1007 * Queue it on the new socket if the new socket is active, 1001 * Queue it on the new socket if the new socket is active,
1008 * otherwise we just shortcircuit this and continue with 1002 * otherwise we just shortcircuit this and continue with
1009 * the new socket.. 1003 * the new socket..
1010 */ 1004 */
1011 if(nsk != sk) { 1005 if (nsk != sk) {
1012 if (dccp_child_process(sk, nsk, skb)) 1006 if (dccp_child_process(sk, nsk, skb))
1013 goto reset; 1007 goto reset;
1014 if (opt_skb) 1008 if (opt_skb != NULL)
1015 __kfree_skb(opt_skb); 1009 __kfree_skb(opt_skb);
1016 return 0; 1010 return 0;
1017 } 1011 }
@@ -1024,7 +1018,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1024reset: 1018reset:
1025 dccp_v6_ctl_send_reset(skb); 1019 dccp_v6_ctl_send_reset(skb);
1026discard: 1020discard:
1027 if (opt_skb) 1021 if (opt_skb != NULL)
1028 __kfree_skb(opt_skb); 1022 __kfree_skb(opt_skb);
1029 kfree_skb(skb); 1023 kfree_skb(skb);
1030 return 0; 1024 return 0;
@@ -1057,7 +1051,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1057 dh->dccph_sport, 1051 dh->dccph_sport,
1058 &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport), 1052 &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
1059 inet6_iif(skb)); 1053 inet6_iif(skb));
1060 /* 1054 /*
1061 * Step 2: 1055 * Step 2:
1062 * If no socket ... 1056 * If no socket ...
1063 * Generate Reset(No Connection) unless P.type == Reset 1057 * Generate Reset(No Connection) unless P.type == Reset
@@ -1066,15 +1060,14 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1066 if (sk == NULL) 1060 if (sk == NULL)
1067 goto no_dccp_socket; 1061 goto no_dccp_socket;
1068 1062
1069 /* 1063 /*
1070 * Step 2: 1064 * Step 2:
1071 * ... or S.state == TIMEWAIT, 1065 * ... or S.state == TIMEWAIT,
1072 * Generate Reset(No Connection) unless P.type == Reset 1066 * Generate Reset(No Connection) unless P.type == Reset
1073 * Drop packet and return 1067 * Drop packet and return
1074 */ 1068 */
1075
1076 if (sk->sk_state == DCCP_TIME_WAIT) 1069 if (sk->sk_state == DCCP_TIME_WAIT)
1077 goto do_time_wait; 1070 goto do_time_wait;
1078 1071
1079 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1072 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1080 goto discard_and_relse; 1073 goto discard_and_relse;
@@ -1113,32 +1106,40 @@ do_time_wait:
1113} 1106}
1114 1107
1115static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = { 1108static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
1116 .queue_xmit = inet6_csk_xmit, 1109 .queue_xmit = inet6_csk_xmit,
1117 .send_check = dccp_v6_send_check, 1110 .send_check = dccp_v6_send_check,
1118 .rebuild_header = inet6_sk_rebuild_header, 1111 .rebuild_header = inet6_sk_rebuild_header,
1119 .conn_request = dccp_v6_conn_request, 1112 .conn_request = dccp_v6_conn_request,
1120 .syn_recv_sock = dccp_v6_request_recv_sock, 1113 .syn_recv_sock = dccp_v6_request_recv_sock,
1121 .net_header_len = sizeof(struct ipv6hdr), 1114 .net_header_len = sizeof(struct ipv6hdr),
1122 .setsockopt = ipv6_setsockopt, 1115 .setsockopt = ipv6_setsockopt,
1123 .getsockopt = ipv6_getsockopt, 1116 .getsockopt = ipv6_getsockopt,
1124 .addr2sockaddr = inet6_csk_addr2sockaddr, 1117 .addr2sockaddr = inet6_csk_addr2sockaddr,
1125 .sockaddr_len = sizeof(struct sockaddr_in6) 1118 .sockaddr_len = sizeof(struct sockaddr_in6),
1119#ifdef CONFIG_COMPAT
1120 .compat_setsockopt = compat_ipv6_setsockopt,
1121 .compat_getsockopt = compat_ipv6_getsockopt,
1122#endif
1126}; 1123};
1127 1124
1128/* 1125/*
1129 * DCCP over IPv4 via INET6 API 1126 * DCCP over IPv4 via INET6 API
1130 */ 1127 */
1131static struct inet_connection_sock_af_ops dccp_ipv6_mapped = { 1128static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
1132 .queue_xmit = ip_queue_xmit, 1129 .queue_xmit = ip_queue_xmit,
1133 .send_check = dccp_v4_send_check, 1130 .send_check = dccp_v4_send_check,
1134 .rebuild_header = inet_sk_rebuild_header, 1131 .rebuild_header = inet_sk_rebuild_header,
1135 .conn_request = dccp_v6_conn_request, 1132 .conn_request = dccp_v6_conn_request,
1136 .syn_recv_sock = dccp_v6_request_recv_sock, 1133 .syn_recv_sock = dccp_v6_request_recv_sock,
1137 .net_header_len = sizeof(struct iphdr), 1134 .net_header_len = sizeof(struct iphdr),
1138 .setsockopt = ipv6_setsockopt, 1135 .setsockopt = ipv6_setsockopt,
1139 .getsockopt = ipv6_getsockopt, 1136 .getsockopt = ipv6_getsockopt,
1140 .addr2sockaddr = inet6_csk_addr2sockaddr, 1137 .addr2sockaddr = inet6_csk_addr2sockaddr,
1141 .sockaddr_len = sizeof(struct sockaddr_in6) 1138 .sockaddr_len = sizeof(struct sockaddr_in6),
1139#ifdef CONFIG_COMPAT
1140 .compat_setsockopt = compat_ipv6_setsockopt,
1141 .compat_getsockopt = compat_ipv6_getsockopt,
1142#endif
1142}; 1143};
1143 1144
1144/* NOTE: A lot of things set to zero explicitly by call to 1145/* NOTE: A lot of things set to zero explicitly by call to
@@ -1146,71 +1147,83 @@ static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
1146 */ 1147 */
1147static int dccp_v6_init_sock(struct sock *sk) 1148static int dccp_v6_init_sock(struct sock *sk)
1148{ 1149{
1149 int err = dccp_v4_init_sock(sk); 1150 static __u8 dccp_v6_ctl_sock_initialized;
1151 int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
1150 1152
1151 if (err == 0) 1153 if (err == 0) {
1154 if (unlikely(!dccp_v6_ctl_sock_initialized))
1155 dccp_v6_ctl_sock_initialized = 1;
1152 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops; 1156 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1157 }
1153 1158
1154 return err; 1159 return err;
1155} 1160}
1156 1161
1157static int dccp_v6_destroy_sock(struct sock *sk) 1162static int dccp_v6_destroy_sock(struct sock *sk)
1158{ 1163{
1159 dccp_v4_destroy_sock(sk); 1164 dccp_destroy_sock(sk);
1160 return inet6_destroy_sock(sk); 1165 return inet6_destroy_sock(sk);
1161} 1166}
1162 1167
1163static struct proto dccp_v6_prot = { 1168static struct proto dccp_v6_prot = {
1164 .name = "DCCPv6", 1169 .name = "DCCPv6",
1165 .owner = THIS_MODULE, 1170 .owner = THIS_MODULE,
1166 .close = dccp_close, 1171 .close = dccp_close,
1167 .connect = dccp_v6_connect, 1172 .connect = dccp_v6_connect,
1168 .disconnect = dccp_disconnect, 1173 .disconnect = dccp_disconnect,
1169 .ioctl = dccp_ioctl, 1174 .ioctl = dccp_ioctl,
1170 .init = dccp_v6_init_sock, 1175 .init = dccp_v6_init_sock,
1171 .setsockopt = dccp_setsockopt, 1176 .setsockopt = dccp_setsockopt,
1172 .getsockopt = dccp_getsockopt, 1177 .getsockopt = dccp_getsockopt,
1173 .sendmsg = dccp_sendmsg, 1178 .sendmsg = dccp_sendmsg,
1174 .recvmsg = dccp_recvmsg, 1179 .recvmsg = dccp_recvmsg,
1175 .backlog_rcv = dccp_v6_do_rcv, 1180 .backlog_rcv = dccp_v6_do_rcv,
1176 .hash = dccp_v6_hash, 1181 .hash = dccp_v6_hash,
1177 .unhash = dccp_unhash, 1182 .unhash = dccp_unhash,
1178 .accept = inet_csk_accept, 1183 .accept = inet_csk_accept,
1179 .get_port = dccp_v6_get_port, 1184 .get_port = dccp_v6_get_port,
1180 .shutdown = dccp_shutdown, 1185 .shutdown = dccp_shutdown,
1181 .destroy = dccp_v6_destroy_sock, 1186 .destroy = dccp_v6_destroy_sock,
1182 .orphan_count = &dccp_orphan_count, 1187 .orphan_count = &dccp_orphan_count,
1183 .max_header = MAX_DCCP_HEADER, 1188 .max_header = MAX_DCCP_HEADER,
1184 .obj_size = sizeof(struct dccp6_sock), 1189 .obj_size = sizeof(struct dccp6_sock),
1185 .rsk_prot = &dccp6_request_sock_ops, 1190 .rsk_prot = &dccp6_request_sock_ops,
1186 .twsk_prot = &dccp6_timewait_sock_ops, 1191 .twsk_prot = &dccp6_timewait_sock_ops,
1192#ifdef CONFIG_COMPAT
1193 .compat_setsockopt = compat_dccp_setsockopt,
1194 .compat_getsockopt = compat_dccp_getsockopt,
1195#endif
1187}; 1196};
1188 1197
1189static struct inet6_protocol dccp_v6_protocol = { 1198static struct inet6_protocol dccp_v6_protocol = {
1190 .handler = dccp_v6_rcv, 1199 .handler = dccp_v6_rcv,
1191 .err_handler = dccp_v6_err, 1200 .err_handler = dccp_v6_err,
1192 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, 1201 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
1193}; 1202};
1194 1203
1195static struct proto_ops inet6_dccp_ops = { 1204static struct proto_ops inet6_dccp_ops = {
1196 .family = PF_INET6, 1205 .family = PF_INET6,
1197 .owner = THIS_MODULE, 1206 .owner = THIS_MODULE,
1198 .release = inet6_release, 1207 .release = inet6_release,
1199 .bind = inet6_bind, 1208 .bind = inet6_bind,
1200 .connect = inet_stream_connect, 1209 .connect = inet_stream_connect,
1201 .socketpair = sock_no_socketpair, 1210 .socketpair = sock_no_socketpair,
1202 .accept = inet_accept, 1211 .accept = inet_accept,
1203 .getname = inet6_getname, 1212 .getname = inet6_getname,
1204 .poll = dccp_poll, 1213 .poll = dccp_poll,
1205 .ioctl = inet6_ioctl, 1214 .ioctl = inet6_ioctl,
1206 .listen = inet_dccp_listen, 1215 .listen = inet_dccp_listen,
1207 .shutdown = inet_shutdown, 1216 .shutdown = inet_shutdown,
1208 .setsockopt = sock_common_setsockopt, 1217 .setsockopt = sock_common_setsockopt,
1209 .getsockopt = sock_common_getsockopt, 1218 .getsockopt = sock_common_getsockopt,
1210 .sendmsg = inet_sendmsg, 1219 .sendmsg = inet_sendmsg,
1211 .recvmsg = sock_common_recvmsg, 1220 .recvmsg = sock_common_recvmsg,
1212 .mmap = sock_no_mmap, 1221 .mmap = sock_no_mmap,
1213 .sendpage = sock_no_sendpage, 1222 .sendpage = sock_no_sendpage,
1223#ifdef CONFIG_COMPAT
1224 .compat_setsockopt = compat_sock_common_setsockopt,
1225 .compat_getsockopt = compat_sock_common_getsockopt,
1226#endif
1214}; 1227};
1215 1228
1216static struct inet_protosw dccp_v6_protosw = { 1229static struct inet_protosw dccp_v6_protosw = {
@@ -1234,8 +1247,16 @@ static int __init dccp_v6_init(void)
1234 goto out_unregister_proto; 1247 goto out_unregister_proto;
1235 1248
1236 inet6_register_protosw(&dccp_v6_protosw); 1249 inet6_register_protosw(&dccp_v6_protosw);
1250
1251 err = inet_csk_ctl_sock_create(&dccp_v6_ctl_socket, PF_INET6,
1252 SOCK_DCCP, IPPROTO_DCCP);
1253 if (err != 0)
1254 goto out_unregister_protosw;
1237out: 1255out:
1238 return err; 1256 return err;
1257out_unregister_protosw:
1258 inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1259 inet6_unregister_protosw(&dccp_v6_protosw);
1239out_unregister_proto: 1260out_unregister_proto:
1240 proto_unregister(&dccp_v6_prot); 1261 proto_unregister(&dccp_v6_prot);
1241 goto out; 1262 goto out;