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