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