]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/dccp/ipv6.c
[DCCP]: calling dccp_v{4,6}_reqsk_send_ack is a BUG
[linux-2.6-omap-h63xx.git] / net / dccp / ipv6.c
1 /*
2  *      DCCP over IPv6
3  *      Linux INET6 implementation
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
15 #include <linux/module.h>
16 #include <linux/random.h>
17 #include <linux/xfrm.h>
18
19 #include <net/addrconf.h>
20 #include <net/inet_common.h>
21 #include <net/inet_hashtables.h>
22 #include <net/inet_sock.h>
23 #include <net/inet6_connection_sock.h>
24 #include <net/inet6_hashtables.h>
25 #include <net/ip6_route.h>
26 #include <net/ipv6.h>
27 #include <net/protocol.h>
28 #include <net/transp_v6.h>
29 #include <net/ip6_checksum.h>
30 #include <net/xfrm.h>
31
32 #include "dccp.h"
33 #include "ipv6.h"
34 #include "feat.h"
35
36 /* Socket used for sending RSTs and ACKs */
37 static struct socket *dccp_v6_ctl_socket;
38
39 static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
40 static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
41
42 static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
43
44 static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
45 static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
46
47 static int dccp_v6_get_port(struct sock *sk, unsigned short snum)
48 {
49         return inet_csk_get_port(&dccp_hashinfo, sk, snum,
50                                  inet6_csk_bind_conflict);
51 }
52
53 static void dccp_v6_hash(struct sock *sk)
54 {
55         if (sk->sk_state != DCCP_CLOSED) {
56                 if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
57                         dccp_hash(sk);
58                         return;
59                 }
60                 local_bh_disable();
61                 __inet6_hash(&dccp_hashinfo, sk);
62                 local_bh_enable();
63         }
64 }
65
66 static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len,
67                                 struct in6_addr *saddr,
68                                 struct in6_addr *daddr,
69                                 unsigned long base)
70 {
71         return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base);
72 }
73
74 static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
75 {
76         const struct dccp_hdr *dh = dccp_hdr(skb);
77
78         if (skb->protocol == htons(ETH_P_IPV6))
79                 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
80                                                     skb->nh.ipv6h->saddr.s6_addr32,
81                                                     dh->dccph_dport,
82                                                     dh->dccph_sport);
83
84         return secure_dccp_sequence_number(skb->nh.iph->daddr,
85                                            skb->nh.iph->saddr,
86                                            dh->dccph_dport,
87                                            dh->dccph_sport);
88 }
89
90 static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
91                            int addr_len)
92 {
93         struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
94         struct inet_connection_sock *icsk = inet_csk(sk);
95         struct inet_sock *inet = inet_sk(sk);
96         struct ipv6_pinfo *np = inet6_sk(sk);
97         struct dccp_sock *dp = dccp_sk(sk);
98         struct in6_addr *saddr = NULL, *final_p = NULL, final;
99         struct flowi fl;
100         struct dst_entry *dst;
101         int addr_type;
102         int err;
103
104         dp->dccps_role = DCCP_ROLE_CLIENT;
105
106         if (addr_len < SIN6_LEN_RFC2133)
107                 return -EINVAL;
108
109         if (usin->sin6_family != AF_INET6)
110                 return -EAFNOSUPPORT;
111
112         memset(&fl, 0, sizeof(fl));
113
114         if (np->sndflow) {
115                 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
116                 IP6_ECN_flow_init(fl.fl6_flowlabel);
117                 if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
118                         struct ip6_flowlabel *flowlabel;
119                         flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
120                         if (flowlabel == NULL)
121                                 return -EINVAL;
122                         ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
123                         fl6_sock_release(flowlabel);
124                 }
125         }
126         /*
127          * connect() to INADDR_ANY means loopback (BSD'ism).
128          */
129         if (ipv6_addr_any(&usin->sin6_addr))
130                 usin->sin6_addr.s6_addr[15] = 1;
131
132         addr_type = ipv6_addr_type(&usin->sin6_addr);
133
134         if (addr_type & IPV6_ADDR_MULTICAST)
135                 return -ENETUNREACH;
136
137         if (addr_type & IPV6_ADDR_LINKLOCAL) {
138                 if (addr_len >= sizeof(struct sockaddr_in6) &&
139                     usin->sin6_scope_id) {
140                         /* If interface is set while binding, indices
141                          * must coincide.
142                          */
143                         if (sk->sk_bound_dev_if &&
144                             sk->sk_bound_dev_if != usin->sin6_scope_id)
145                                 return -EINVAL;
146
147                         sk->sk_bound_dev_if = usin->sin6_scope_id;
148                 }
149
150                 /* Connect to link-local address requires an interface */
151                 if (!sk->sk_bound_dev_if)
152                         return -EINVAL;
153         }
154
155         ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
156         np->flow_label = fl.fl6_flowlabel;
157
158         /*
159          * DCCP over IPv4
160          */
161         if (addr_type == IPV6_ADDR_MAPPED) {
162                 u32 exthdrlen = icsk->icsk_ext_hdr_len;
163                 struct sockaddr_in sin;
164
165                 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
166
167                 if (__ipv6_only_sock(sk))
168                         return -ENETUNREACH;
169
170                 sin.sin_family = AF_INET;
171                 sin.sin_port = usin->sin6_port;
172                 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
173
174                 icsk->icsk_af_ops = &dccp_ipv6_mapped;
175                 sk->sk_backlog_rcv = dccp_v4_do_rcv;
176
177                 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
178                 if (err) {
179                         icsk->icsk_ext_hdr_len = exthdrlen;
180                         icsk->icsk_af_ops = &dccp_ipv6_af_ops;
181                         sk->sk_backlog_rcv = dccp_v6_do_rcv;
182                         goto failure;
183                 } else {
184                         ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
185                                       inet->saddr);
186                         ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
187                                       inet->rcv_saddr);
188                 }
189
190                 return err;
191         }
192
193         if (!ipv6_addr_any(&np->rcv_saddr))
194                 saddr = &np->rcv_saddr;
195
196         fl.proto = IPPROTO_DCCP;
197         ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
198         ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
199         fl.oif = sk->sk_bound_dev_if;
200         fl.fl_ip_dport = usin->sin6_port;
201         fl.fl_ip_sport = inet->sport;
202         security_sk_classify_flow(sk, &fl);
203
204         if (np->opt != NULL && np->opt->srcrt != NULL) {
205                 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
206
207                 ipv6_addr_copy(&final, &fl.fl6_dst);
208                 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
209                 final_p = &final;
210         }
211
212         err = ip6_dst_lookup(sk, &dst, &fl);
213         if (err)
214                 goto failure;
215
216         if (final_p)
217                 ipv6_addr_copy(&fl.fl6_dst, final_p);
218
219         err = xfrm_lookup(&dst, &fl, sk, 0);
220         if (err < 0)
221                 goto failure;
222
223         if (saddr == NULL) {
224                 saddr = &fl.fl6_src;
225                 ipv6_addr_copy(&np->rcv_saddr, saddr);
226         }
227
228         /* set the source address */
229         ipv6_addr_copy(&np->saddr, saddr);
230         inet->rcv_saddr = LOOPBACK4_IPV6;
231
232         __ip6_dst_store(sk, dst, NULL, NULL);
233
234         icsk->icsk_ext_hdr_len = 0;
235         if (np->opt != NULL)
236                 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
237                                           np->opt->opt_nflen);
238
239         inet->dport = usin->sin6_port;
240
241         dccp_set_state(sk, DCCP_REQUESTING);
242         err = inet6_hash_connect(&dccp_death_row, sk);
243         if (err)
244                 goto late_failure;
245         /* FIXME */
246 #if 0
247         dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
248                                                        np->daddr.s6_addr32,
249                                                        inet->sport,
250                                                        inet->dport);
251 #endif
252         err = dccp_connect(sk);
253         if (err)
254                 goto late_failure;
255
256         return 0;
257
258 late_failure:
259         dccp_set_state(sk, DCCP_CLOSED);
260         __sk_dst_reset(sk);
261 failure:
262         inet->dport = 0;
263         sk->sk_route_caps = 0;
264         return err;
265 }
266
267 static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
268                         int type, int code, int offset, __be32 info)
269 {
270         struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
271         const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
272         struct ipv6_pinfo *np;
273         struct sock *sk;
274         int err;
275         __u64 seq;
276
277         sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
278                           &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
279
280         if (sk == NULL) {
281                 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
282                 return;
283         }
284
285         if (sk->sk_state == DCCP_TIME_WAIT) {
286                 inet_twsk_put(inet_twsk(sk));
287                 return;
288         }
289
290         bh_lock_sock(sk);
291         if (sock_owned_by_user(sk))
292                 NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
293
294         if (sk->sk_state == DCCP_CLOSED)
295                 goto out;
296
297         np = inet6_sk(sk);
298
299         if (type == ICMPV6_PKT_TOOBIG) {
300                 struct dst_entry *dst = NULL;
301
302                 if (sock_owned_by_user(sk))
303                         goto out;
304                 if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
305                         goto out;
306
307                 /* icmp should have updated the destination cache entry */
308                 dst = __sk_dst_check(sk, np->dst_cookie);
309                 if (dst == NULL) {
310                         struct inet_sock *inet = inet_sk(sk);
311                         struct flowi fl;
312
313                         /* BUGGG_FUTURE: Again, it is not clear how
314                            to handle rthdr case. Ignore this complexity
315                            for now.
316                          */
317                         memset(&fl, 0, sizeof(fl));
318                         fl.proto = IPPROTO_DCCP;
319                         ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
320                         ipv6_addr_copy(&fl.fl6_src, &np->saddr);
321                         fl.oif = sk->sk_bound_dev_if;
322                         fl.fl_ip_dport = inet->dport;
323                         fl.fl_ip_sport = inet->sport;
324                         security_sk_classify_flow(sk, &fl);
325
326                         err = ip6_dst_lookup(sk, &dst, &fl);
327                         if (err) {
328                                 sk->sk_err_soft = -err;
329                                 goto out;
330                         }
331
332                         err = xfrm_lookup(&dst, &fl, sk, 0);
333                         if (err < 0) {
334                                 sk->sk_err_soft = -err;
335                                 goto out;
336                         }
337                 } else
338                         dst_hold(dst);
339
340                 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
341                         dccp_sync_mss(sk, dst_mtu(dst));
342                 } /* else let the usual retransmit timer handle it */
343                 dst_release(dst);
344                 goto out;
345         }
346
347         icmpv6_err_convert(type, code, &err);
348
349         seq = DCCP_SKB_CB(skb)->dccpd_seq;
350         /* Might be for an request_sock */
351         switch (sk->sk_state) {
352                 struct request_sock *req, **prev;
353         case DCCP_LISTEN:
354                 if (sock_owned_by_user(sk))
355                         goto out;
356
357                 req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
358                                            &hdr->daddr, &hdr->saddr,
359                                            inet6_iif(skb));
360                 if (req == NULL)
361                         goto out;
362
363                 /*
364                  * ICMPs are not backlogged, hence we cannot get an established
365                  * socket here.
366                  */
367                 BUG_TRAP(req->sk == NULL);
368
369                 if (seq != dccp_rsk(req)->dreq_iss) {
370                         NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
371                         goto out;
372                 }
373
374                 inet_csk_reqsk_queue_drop(sk, req, prev);
375                 goto out;
376
377         case DCCP_REQUESTING:
378         case DCCP_RESPOND:  /* Cannot happen.
379                                It can, it SYNs are crossed. --ANK */
380                 if (!sock_owned_by_user(sk)) {
381                         DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
382                         sk->sk_err = err;
383                         /*
384                          * Wake people up to see the error
385                          * (see connect in sock.c)
386                          */
387                         sk->sk_error_report(sk);
388                         dccp_done(sk);
389                 } else
390                         sk->sk_err_soft = err;
391                 goto out;
392         }
393
394         if (!sock_owned_by_user(sk) && np->recverr) {
395                 sk->sk_err = err;
396                 sk->sk_error_report(sk);
397         } else
398                 sk->sk_err_soft = err;
399
400 out:
401         bh_unlock_sock(sk);
402         sock_put(sk);
403 }
404
405
406 static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
407                                  struct dst_entry *dst)
408 {
409         struct inet6_request_sock *ireq6 = inet6_rsk(req);
410         struct ipv6_pinfo *np = inet6_sk(sk);
411         struct sk_buff *skb;
412         struct ipv6_txoptions *opt = NULL;
413         struct in6_addr *final_p = NULL, final;
414         struct flowi fl;
415         int err = -1;
416
417         memset(&fl, 0, sizeof(fl));
418         fl.proto = IPPROTO_DCCP;
419         ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
420         ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
421         fl.fl6_flowlabel = 0;
422         fl.oif = ireq6->iif;
423         fl.fl_ip_dport = inet_rsk(req)->rmt_port;
424         fl.fl_ip_sport = inet_sk(sk)->sport;
425         security_req_classify_flow(req, &fl);
426
427         if (dst == NULL) {
428                 opt = np->opt;
429                 if (opt == NULL &&
430                     np->rxopt.bits.osrcrt == 2 &&
431                     ireq6->pktopts) {
432                         struct sk_buff *pktopts = ireq6->pktopts;
433                         struct inet6_skb_parm *rxopt = IP6CB(pktopts);
434
435                         if (rxopt->srcrt)
436                                 opt = ipv6_invert_rthdr(sk,
437                                         (struct ipv6_rt_hdr *)(pktopts->nh.raw +
438                                                                rxopt->srcrt));
439                 }
440
441                 if (opt != NULL && opt->srcrt != NULL) {
442                         const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
443
444                         ipv6_addr_copy(&final, &fl.fl6_dst);
445                         ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
446                         final_p = &final;
447                 }
448
449                 err = ip6_dst_lookup(sk, &dst, &fl);
450                 if (err)
451                         goto done;
452
453                 if (final_p)
454                         ipv6_addr_copy(&fl.fl6_dst, final_p);
455
456                 err = xfrm_lookup(&dst, &fl, sk, 0);
457                 if (err < 0)
458                         goto done;
459         }
460
461         skb = dccp_make_response(sk, dst, req);
462         if (skb != NULL) {
463                 struct dccp_hdr *dh = dccp_hdr(skb);
464
465                 dh->dccph_checksum = dccp_v6_check(dh, skb->len,
466                                                    &ireq6->loc_addr,
467                                                    &ireq6->rmt_addr,
468                                                    csum_partial((char *)dh,
469                                                                 skb->len,
470                                                                 skb->csum));
471                 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
472                 err = ip6_xmit(sk, skb, &fl, opt, 0);
473                 if (err == NET_XMIT_CN)
474                         err = 0;
475         }
476
477 done:
478         if (opt != NULL && opt != np->opt)
479                 sock_kfree_s(sk, opt, opt->tot_len);
480         dst_release(dst);
481         return err;
482 }
483
484 static void dccp_v6_reqsk_destructor(struct request_sock *req)
485 {
486         if (inet6_rsk(req)->pktopts != NULL)
487                 kfree_skb(inet6_rsk(req)->pktopts);
488 }
489
490 static struct request_sock_ops dccp6_request_sock_ops = {
491         .family         = AF_INET6,
492         .obj_size       = sizeof(struct dccp6_request_sock),
493         .rtx_syn_ack    = dccp_v6_send_response,
494         .send_ack       = dccp_reqsk_send_ack,
495         .destructor     = dccp_v6_reqsk_destructor,
496         .send_reset     = dccp_v6_ctl_send_reset,
497 };
498
499 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
500         .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
501 };
502
503 static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
504 {
505         struct ipv6_pinfo *np = inet6_sk(sk);
506         struct dccp_hdr *dh = dccp_hdr(skb);
507
508         dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
509                                              len, IPPROTO_DCCP,
510                                              csum_partial((char *)dh,
511                                                           dh->dccph_doff << 2,
512                                                           skb->csum));
513 }
514
515 static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
516 {
517         struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
518         const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
519                                        sizeof(struct dccp_hdr_ext) +
520                                        sizeof(struct dccp_hdr_reset);
521         struct sk_buff *skb;
522         struct flowi fl;
523         u64 seqno;
524
525         if (rxdh->dccph_type == DCCP_PKT_RESET)
526                 return;
527
528         if (!ipv6_unicast_destination(rxskb))
529                 return;
530
531         skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
532                         GFP_ATOMIC);
533         if (skb == NULL)
534                 return;
535
536         skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
537
538         dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
539
540         /* Swap the send and the receive. */
541         dh->dccph_type  = DCCP_PKT_RESET;
542         dh->dccph_sport = rxdh->dccph_dport;
543         dh->dccph_dport = rxdh->dccph_sport;
544         dh->dccph_doff  = dccp_hdr_reset_len / 4;
545         dh->dccph_x     = 1;
546         dccp_hdr_reset(skb)->dccph_reset_code =
547                                 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
548
549         /* See "8.3.1. Abnormal Termination" in RFC 4340 */
550         seqno = 0;
551         if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
552                 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
553
554         dccp_hdr_set_seq(dh, seqno);
555         dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
556                          DCCP_SKB_CB(rxskb)->dccpd_seq);
557
558         memset(&fl, 0, sizeof(fl));
559         ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
560         ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
561         dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
562                                              sizeof(*dh), IPPROTO_DCCP,
563                                              skb->csum);
564         fl.proto = IPPROTO_DCCP;
565         fl.oif = inet6_iif(rxskb);
566         fl.fl_ip_dport = dh->dccph_dport;
567         fl.fl_ip_sport = dh->dccph_sport;
568         security_skb_classify_flow(rxskb, &fl);
569
570         /* sk = NULL, but it is safe for now. RST socket required. */
571         if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
572                 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
573                         ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
574                         DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
575                         DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
576                         return;
577                 }
578         }
579
580         kfree_skb(skb);
581 }
582
583 static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
584 {
585         const struct dccp_hdr *dh = dccp_hdr(skb);
586         const struct ipv6hdr *iph = skb->nh.ipv6h;
587         struct sock *nsk;
588         struct request_sock **prev;
589         /* Find possible connection requests. */
590         struct request_sock *req = inet6_csk_search_req(sk, &prev,
591                                                         dh->dccph_sport,
592                                                         &iph->saddr,
593                                                         &iph->daddr,
594                                                         inet6_iif(skb));
595         if (req != NULL)
596                 return dccp_check_req(sk, skb, req, prev);
597
598         nsk = __inet6_lookup_established(&dccp_hashinfo,
599                                          &iph->saddr, dh->dccph_sport,
600                                          &iph->daddr, ntohs(dh->dccph_dport),
601                                          inet6_iif(skb));
602         if (nsk != NULL) {
603                 if (nsk->sk_state != DCCP_TIME_WAIT) {
604                         bh_lock_sock(nsk);
605                         return nsk;
606                 }
607                 inet_twsk_put(inet_twsk(nsk));
608                 return NULL;
609         }
610
611         return sk;
612 }
613
614 static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
615 {
616         struct dccp_sock dp;
617         struct request_sock *req;
618         struct dccp_request_sock *dreq;
619         struct inet6_request_sock *ireq6;
620         struct ipv6_pinfo *np = inet6_sk(sk);
621         const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
622         struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
623         __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
624
625         if (skb->protocol == htons(ETH_P_IP))
626                 return dccp_v4_conn_request(sk, skb);
627
628         if (!ipv6_unicast_destination(skb))
629                 goto drop;
630
631         if (dccp_bad_service_code(sk, service)) {
632                 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
633                 goto drop;
634         }
635         /*
636          * There are no SYN attacks on IPv6, yet...
637          */
638         if (inet_csk_reqsk_queue_is_full(sk))
639                 goto drop;
640
641         if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
642                 goto drop;
643
644         req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
645         if (req == NULL)
646                 goto drop;
647
648         /* FIXME: process options */
649
650         dccp_openreq_init(req, &dp, skb);
651
652         if (security_inet_conn_request(sk, skb, req))
653                 goto drop_and_free;
654
655         ireq6 = inet6_rsk(req);
656         ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
657         ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
658         req->rcv_wnd    = dccp_feat_default_sequence_window;
659         ireq6->pktopts  = NULL;
660
661         if (ipv6_opt_accepted(sk, skb) ||
662             np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
663             np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
664                 atomic_inc(&skb->users);
665                 ireq6->pktopts = skb;
666         }
667         ireq6->iif = sk->sk_bound_dev_if;
668
669         /* So that link locals have meaning */
670         if (!sk->sk_bound_dev_if &&
671             ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
672                 ireq6->iif = inet6_iif(skb);
673
674         /*
675          * Step 3: Process LISTEN state
676          *
677          * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
678          *
679          * In fact we defer setting S.GSR, S.SWL, S.SWH to
680          * dccp_create_openreq_child.
681          */
682         dreq = dccp_rsk(req);
683         dreq->dreq_isr     = dcb->dccpd_seq;
684         dreq->dreq_iss     = dccp_v6_init_sequence(sk, skb);
685         dreq->dreq_service = service;
686
687         if (dccp_v6_send_response(sk, req, NULL))
688                 goto drop_and_free;
689
690         inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
691         return 0;
692
693 drop_and_free:
694         reqsk_free(req);
695 drop:
696         DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
697         dcb->dccpd_reset_code = reset_code;
698         return -1;
699 }
700
701 static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
702                                               struct sk_buff *skb,
703                                               struct request_sock *req,
704                                               struct dst_entry *dst)
705 {
706         struct inet6_request_sock *ireq6 = inet6_rsk(req);
707         struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
708         struct inet_sock *newinet;
709         struct dccp_sock *newdp;
710         struct dccp6_sock *newdp6;
711         struct sock *newsk;
712         struct ipv6_txoptions *opt;
713
714         if (skb->protocol == htons(ETH_P_IP)) {
715                 /*
716                  *      v6 mapped
717                  */
718                 newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
719                 if (newsk == NULL)
720                         return NULL;
721
722                 newdp6 = (struct dccp6_sock *)newsk;
723                 newdp = dccp_sk(newsk);
724                 newinet = inet_sk(newsk);
725                 newinet->pinet6 = &newdp6->inet6;
726                 newnp = inet6_sk(newsk);
727
728                 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
729
730                 ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
731                               newinet->daddr);
732
733                 ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
734                               newinet->saddr);
735
736                 ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
737
738                 inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
739                 newsk->sk_backlog_rcv = dccp_v4_do_rcv;
740                 newnp->pktoptions  = NULL;
741                 newnp->opt         = NULL;
742                 newnp->mcast_oif   = inet6_iif(skb);
743                 newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
744
745                 /*
746                  * No need to charge this sock to the relevant IPv6 refcnt debug socks count
747                  * here, dccp_create_openreq_child now does this for us, see the comment in
748                  * that function for the gory details. -acme
749                  */
750
751                 /* It is tricky place. Until this moment IPv4 tcp
752                    worked with IPv6 icsk.icsk_af_ops.
753                    Sync it now.
754                  */
755                 dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
756
757                 return newsk;
758         }
759
760         opt = np->opt;
761
762         if (sk_acceptq_is_full(sk))
763                 goto out_overflow;
764
765         if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
766                 const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
767
768                 if (rxopt->srcrt)
769                         opt = ipv6_invert_rthdr(sk,
770                                 (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
771                                                        rxopt->srcrt));
772         }
773
774         if (dst == NULL) {
775                 struct in6_addr *final_p = NULL, final;
776                 struct flowi fl;
777
778                 memset(&fl, 0, sizeof(fl));
779                 fl.proto = IPPROTO_DCCP;
780                 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
781                 if (opt != NULL && opt->srcrt != NULL) {
782                         const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
783
784                         ipv6_addr_copy(&final, &fl.fl6_dst);
785                         ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
786                         final_p = &final;
787                 }
788                 ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
789                 fl.oif = sk->sk_bound_dev_if;
790                 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
791                 fl.fl_ip_sport = inet_sk(sk)->sport;
792                 security_sk_classify_flow(sk, &fl);
793
794                 if (ip6_dst_lookup(sk, &dst, &fl))
795                         goto out;
796
797                 if (final_p)
798                         ipv6_addr_copy(&fl.fl6_dst, final_p);
799
800                 if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
801                         goto out;
802         }
803
804         newsk = dccp_create_openreq_child(sk, req, skb);
805         if (newsk == NULL)
806                 goto out;
807
808         /*
809          * No need to charge this sock to the relevant IPv6 refcnt debug socks
810          * count here, dccp_create_openreq_child now does this for us, see the
811          * comment in that function for the gory details. -acme
812          */
813
814         __ip6_dst_store(newsk, dst, NULL, NULL);
815         newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
816                                                       NETIF_F_TSO);
817         newdp6 = (struct dccp6_sock *)newsk;
818         newinet = inet_sk(newsk);
819         newinet->pinet6 = &newdp6->inet6;
820         newdp = dccp_sk(newsk);
821         newnp = inet6_sk(newsk);
822
823         memcpy(newnp, np, sizeof(struct ipv6_pinfo));
824
825         ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr);
826         ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr);
827         ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr);
828         newsk->sk_bound_dev_if = ireq6->iif;
829
830         /* Now IPv6 options...
831
832            First: no IPv4 options.
833          */
834         newinet->opt = NULL;
835
836         /* Clone RX bits */
837         newnp->rxopt.all = np->rxopt.all;
838
839         /* Clone pktoptions received with SYN */
840         newnp->pktoptions = NULL;
841         if (ireq6->pktopts != NULL) {
842                 newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC);
843                 kfree_skb(ireq6->pktopts);
844                 ireq6->pktopts = NULL;
845                 if (newnp->pktoptions)
846                         skb_set_owner_r(newnp->pktoptions, newsk);
847         }
848         newnp->opt        = NULL;
849         newnp->mcast_oif  = inet6_iif(skb);
850         newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
851
852         /*
853          * Clone native IPv6 options from listening socket (if any)
854          *
855          * Yes, keeping reference count would be much more clever, but we make
856          * one more one thing there: reattach optmem to newsk.
857          */
858         if (opt != NULL) {
859                 newnp->opt = ipv6_dup_options(newsk, opt);
860                 if (opt != np->opt)
861                         sock_kfree_s(sk, opt, opt->tot_len);
862         }
863
864         inet_csk(newsk)->icsk_ext_hdr_len = 0;
865         if (newnp->opt != NULL)
866                 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
867                                                      newnp->opt->opt_flen);
868
869         dccp_sync_mss(newsk, dst_mtu(dst));
870
871         newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
872
873         __inet6_hash(&dccp_hashinfo, newsk);
874         inet_inherit_port(&dccp_hashinfo, sk, newsk);
875
876         return newsk;
877
878 out_overflow:
879         NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
880 out:
881         NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
882         if (opt != NULL && opt != np->opt)
883                 sock_kfree_s(sk, opt, opt->tot_len);
884         dst_release(dst);
885         return NULL;
886 }
887
888 /* The socket must have it's spinlock held when we get
889  * here.
890  *
891  * We have a potential double-lock case here, so even when
892  * doing backlog processing we use the BH locking scheme.
893  * This is because we cannot sleep with the original spinlock
894  * held.
895  */
896 static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
897 {
898         struct ipv6_pinfo *np = inet6_sk(sk);
899         struct sk_buff *opt_skb = NULL;
900
901         /* Imagine: socket is IPv6. IPv4 packet arrives,
902            goes to IPv4 receive handler and backlogged.
903            From backlog it always goes here. Kerboom...
904            Fortunately, dccp_rcv_established and rcv_established
905            handle them correctly, but it is not case with
906            dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
907          */
908
909         if (skb->protocol == htons(ETH_P_IP))
910                 return dccp_v4_do_rcv(sk, skb);
911
912         if (sk_filter(sk, skb))
913                 goto discard;
914
915         /*
916          * socket locking is here for SMP purposes as backlog rcv is currently
917          * called with bh processing disabled.
918          */
919
920         /* Do Stevens' IPV6_PKTOPTIONS.
921
922            Yes, guys, it is the only place in our code, where we
923            may make it not affecting IPv4.
924            The rest of code is protocol independent,
925            and I do not like idea to uglify IPv4.
926
927            Actually, all the idea behind IPV6_PKTOPTIONS
928            looks not very well thought. For now we latch
929            options, received in the last packet, enqueued
930            by tcp. Feel free to propose better solution.
931                                                --ANK (980728)
932          */
933         if (np->rxopt.all)
934         /*
935          * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below
936          *        (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example.
937          */
938                 opt_skb = skb_clone(skb, GFP_ATOMIC);
939
940         if (sk->sk_state == DCCP_OPEN) { /* Fast path */
941                 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
942                         goto reset;
943                 if (opt_skb) {
944                         /* XXX This is where we would goto ipv6_pktoptions. */
945                         __kfree_skb(opt_skb);
946                 }
947                 return 0;
948         }
949
950         if (sk->sk_state == DCCP_LISTEN) {
951                 struct sock *nsk = dccp_v6_hnd_req(sk, skb);
952
953                 if (nsk == NULL)
954                         goto discard;
955                 /*
956                  * Queue it on the new socket if the new socket is active,
957                  * otherwise we just shortcircuit this and continue with
958                  * the new socket..
959                  */
960                 if (nsk != sk) {
961                         if (dccp_child_process(sk, nsk, skb))
962                                 goto reset;
963                         if (opt_skb != NULL)
964                                 __kfree_skb(opt_skb);
965                         return 0;
966                 }
967         }
968
969         if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
970                 goto reset;
971         if (opt_skb) {
972                 /* XXX This is where we would goto ipv6_pktoptions. */
973                 __kfree_skb(opt_skb);
974         }
975         return 0;
976
977 reset:
978         dccp_v6_ctl_send_reset(skb);
979 discard:
980         if (opt_skb != NULL)
981                 __kfree_skb(opt_skb);
982         kfree_skb(skb);
983         return 0;
984 }
985
986 static int dccp_v6_rcv(struct sk_buff **pskb)
987 {
988         const struct dccp_hdr *dh;
989         struct sk_buff *skb = *pskb;
990         struct sock *sk;
991
992         /* Step 1: Check header basics: */
993
994         if (dccp_invalid_packet(skb))
995                 goto discard_it;
996
997         dh = dccp_hdr(skb);
998
999         DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
1000         DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
1001
1002         if (dccp_packet_without_ack(skb))
1003                 DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
1004         else
1005                 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
1006
1007         /* Step 2:
1008          *      Look up flow ID in table and get corresponding socket */
1009         sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
1010                             dh->dccph_sport,
1011                             &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
1012                             inet6_iif(skb));
1013         /*
1014          * Step 2:
1015          *      If no socket ...
1016          *              Generate Reset(No Connection) unless P.type == Reset
1017          *              Drop packet and return
1018          */
1019         if (sk == NULL) {
1020                 dccp_pr_debug("failed to look up flow ID in table and "
1021                               "get corresponding socket\n");
1022                 goto no_dccp_socket;
1023         }
1024
1025         /*
1026          * Step 2:
1027          *      ... or S.state == TIMEWAIT,
1028          *              Generate Reset(No Connection) unless P.type == Reset
1029          *              Drop packet and return
1030          */
1031         if (sk->sk_state == DCCP_TIME_WAIT) {
1032                 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
1033                 inet_twsk_put(inet_twsk(sk));
1034                 goto no_dccp_socket;
1035         }
1036
1037         if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1038                 goto discard_and_relse;
1039
1040         return sk_receive_skb(sk, skb) ? -1 : 0;
1041
1042 no_dccp_socket:
1043         if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1044                 goto discard_it;
1045         /*
1046          * Step 2:
1047          *              Generate Reset(No Connection) unless P.type == Reset
1048          *              Drop packet and return
1049          */
1050         if (dh->dccph_type != DCCP_PKT_RESET) {
1051                 DCCP_SKB_CB(skb)->dccpd_reset_code =
1052                                         DCCP_RESET_CODE_NO_CONNECTION;
1053                 dccp_v6_ctl_send_reset(skb);
1054         }
1055
1056 discard_it:
1057         kfree_skb(skb);
1058         return 0;
1059
1060 discard_and_relse:
1061         sock_put(sk);
1062         goto discard_it;
1063 }
1064
1065 static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
1066         .queue_xmit        = inet6_csk_xmit,
1067         .send_check        = dccp_v6_send_check,
1068         .rebuild_header    = inet6_sk_rebuild_header,
1069         .conn_request      = dccp_v6_conn_request,
1070         .syn_recv_sock     = dccp_v6_request_recv_sock,
1071         .net_header_len    = sizeof(struct ipv6hdr),
1072         .setsockopt        = ipv6_setsockopt,
1073         .getsockopt        = ipv6_getsockopt,
1074         .addr2sockaddr     = inet6_csk_addr2sockaddr,
1075         .sockaddr_len      = sizeof(struct sockaddr_in6),
1076 #ifdef CONFIG_COMPAT
1077         .compat_setsockopt = compat_ipv6_setsockopt,
1078         .compat_getsockopt = compat_ipv6_getsockopt,
1079 #endif
1080 };
1081
1082 /*
1083  *      DCCP over IPv4 via INET6 API
1084  */
1085 static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
1086         .queue_xmit        = ip_queue_xmit,
1087         .send_check        = dccp_v4_send_check,
1088         .rebuild_header    = inet_sk_rebuild_header,
1089         .conn_request      = dccp_v6_conn_request,
1090         .syn_recv_sock     = dccp_v6_request_recv_sock,
1091         .net_header_len    = sizeof(struct iphdr),
1092         .setsockopt        = ipv6_setsockopt,
1093         .getsockopt        = ipv6_getsockopt,
1094         .addr2sockaddr     = inet6_csk_addr2sockaddr,
1095         .sockaddr_len      = sizeof(struct sockaddr_in6),
1096 #ifdef CONFIG_COMPAT
1097         .compat_setsockopt = compat_ipv6_setsockopt,
1098         .compat_getsockopt = compat_ipv6_getsockopt,
1099 #endif
1100 };
1101
1102 /* NOTE: A lot of things set to zero explicitly by call to
1103  *       sk_alloc() so need not be done here.
1104  */
1105 static int dccp_v6_init_sock(struct sock *sk)
1106 {
1107         static __u8 dccp_v6_ctl_sock_initialized;
1108         int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
1109
1110         if (err == 0) {
1111                 if (unlikely(!dccp_v6_ctl_sock_initialized))
1112                         dccp_v6_ctl_sock_initialized = 1;
1113                 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1114         }
1115
1116         return err;
1117 }
1118
1119 static int dccp_v6_destroy_sock(struct sock *sk)
1120 {
1121         dccp_destroy_sock(sk);
1122         return inet6_destroy_sock(sk);
1123 }
1124
1125 static struct proto dccp_v6_prot = {
1126         .name              = "DCCPv6",
1127         .owner             = THIS_MODULE,
1128         .close             = dccp_close,
1129         .connect           = dccp_v6_connect,
1130         .disconnect        = dccp_disconnect,
1131         .ioctl             = dccp_ioctl,
1132         .init              = dccp_v6_init_sock,
1133         .setsockopt        = dccp_setsockopt,
1134         .getsockopt        = dccp_getsockopt,
1135         .sendmsg           = dccp_sendmsg,
1136         .recvmsg           = dccp_recvmsg,
1137         .backlog_rcv       = dccp_v6_do_rcv,
1138         .hash              = dccp_v6_hash,
1139         .unhash            = dccp_unhash,
1140         .accept            = inet_csk_accept,
1141         .get_port          = dccp_v6_get_port,
1142         .shutdown          = dccp_shutdown,
1143         .destroy           = dccp_v6_destroy_sock,
1144         .orphan_count      = &dccp_orphan_count,
1145         .max_header        = MAX_DCCP_HEADER,
1146         .obj_size          = sizeof(struct dccp6_sock),
1147         .rsk_prot          = &dccp6_request_sock_ops,
1148         .twsk_prot         = &dccp6_timewait_sock_ops,
1149 #ifdef CONFIG_COMPAT
1150         .compat_setsockopt = compat_dccp_setsockopt,
1151         .compat_getsockopt = compat_dccp_getsockopt,
1152 #endif
1153 };
1154
1155 static struct inet6_protocol dccp_v6_protocol = {
1156         .handler        = dccp_v6_rcv,
1157         .err_handler    = dccp_v6_err,
1158         .flags          = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
1159 };
1160
1161 static struct proto_ops inet6_dccp_ops = {
1162         .family            = PF_INET6,
1163         .owner             = THIS_MODULE,
1164         .release           = inet6_release,
1165         .bind              = inet6_bind,
1166         .connect           = inet_stream_connect,
1167         .socketpair        = sock_no_socketpair,
1168         .accept            = inet_accept,
1169         .getname           = inet6_getname,
1170         .poll              = dccp_poll,
1171         .ioctl             = inet6_ioctl,
1172         .listen            = inet_dccp_listen,
1173         .shutdown          = inet_shutdown,
1174         .setsockopt        = sock_common_setsockopt,
1175         .getsockopt        = sock_common_getsockopt,
1176         .sendmsg           = inet_sendmsg,
1177         .recvmsg           = sock_common_recvmsg,
1178         .mmap              = sock_no_mmap,
1179         .sendpage          = sock_no_sendpage,
1180 #ifdef CONFIG_COMPAT
1181         .compat_setsockopt = compat_sock_common_setsockopt,
1182         .compat_getsockopt = compat_sock_common_getsockopt,
1183 #endif
1184 };
1185
1186 static struct inet_protosw dccp_v6_protosw = {
1187         .type           = SOCK_DCCP,
1188         .protocol       = IPPROTO_DCCP,
1189         .prot           = &dccp_v6_prot,
1190         .ops            = &inet6_dccp_ops,
1191         .capability     = -1,
1192         .flags          = INET_PROTOSW_ICSK,
1193 };
1194
1195 static int __init dccp_v6_init(void)
1196 {
1197         int err = proto_register(&dccp_v6_prot, 1);
1198
1199         if (err != 0)
1200                 goto out;
1201
1202         err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1203         if (err != 0)
1204                 goto out_unregister_proto;
1205
1206         inet6_register_protosw(&dccp_v6_protosw);
1207
1208         err = inet_csk_ctl_sock_create(&dccp_v6_ctl_socket, PF_INET6,
1209                                        SOCK_DCCP, IPPROTO_DCCP);
1210         if (err != 0)
1211                 goto out_unregister_protosw;
1212 out:
1213         return err;
1214 out_unregister_protosw:
1215         inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1216         inet6_unregister_protosw(&dccp_v6_protosw);
1217 out_unregister_proto:
1218         proto_unregister(&dccp_v6_prot);
1219         goto out;
1220 }
1221
1222 static void __exit dccp_v6_exit(void)
1223 {
1224         inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1225         inet6_unregister_protosw(&dccp_v6_protosw);
1226         proto_unregister(&dccp_v6_prot);
1227 }
1228
1229 module_init(dccp_v6_init);
1230 module_exit(dccp_v6_exit);
1231
1232 /*
1233  * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
1234  * values directly, Also cover the case where the protocol is not specified,
1235  * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
1236  */
1237 MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
1238 MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
1239 MODULE_LICENSE("GPL");
1240 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
1241 MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");