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