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