Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  DCCP over IPv6
0004  *  Linux INET6 implementation
0005  *
0006  *  Based on net/dccp6/ipv6.c
0007  *
0008  *  Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/random.h>
0013 #include <linux/slab.h>
0014 #include <linux/xfrm.h>
0015 #include <linux/string.h>
0016 
0017 #include <net/addrconf.h>
0018 #include <net/inet_common.h>
0019 #include <net/inet_hashtables.h>
0020 #include <net/inet_sock.h>
0021 #include <net/inet6_connection_sock.h>
0022 #include <net/inet6_hashtables.h>
0023 #include <net/ip6_route.h>
0024 #include <net/ipv6.h>
0025 #include <net/protocol.h>
0026 #include <net/transp_v6.h>
0027 #include <net/ip6_checksum.h>
0028 #include <net/xfrm.h>
0029 #include <net/secure_seq.h>
0030 #include <net/netns/generic.h>
0031 #include <net/sock.h>
0032 
0033 #include "dccp.h"
0034 #include "ipv6.h"
0035 #include "feat.h"
0036 
0037 struct dccp_v6_pernet {
0038     struct sock *v6_ctl_sk;
0039 };
0040 
0041 static unsigned int dccp_v6_pernet_id __read_mostly;
0042 
0043 /* The per-net v6_ctl_sk is used for sending RSTs and ACKs */
0044 
0045 static const struct inet_connection_sock_af_ops dccp_ipv6_mapped;
0046 static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
0047 
0048 /* add pseudo-header to DCCP checksum stored in skb->csum */
0049 static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
0050                       const struct in6_addr *saddr,
0051                       const struct in6_addr *daddr)
0052 {
0053     return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
0054 }
0055 
0056 static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb)
0057 {
0058     struct ipv6_pinfo *np = inet6_sk(sk);
0059     struct dccp_hdr *dh = dccp_hdr(skb);
0060 
0061     dccp_csum_outgoing(skb);
0062     dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &sk->sk_v6_daddr);
0063 }
0064 
0065 static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
0066 {
0067     return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
0068                          ipv6_hdr(skb)->saddr.s6_addr32,
0069                          dccp_hdr(skb)->dccph_dport,
0070                          dccp_hdr(skb)->dccph_sport     );
0071 
0072 }
0073 
0074 static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
0075             u8 type, u8 code, int offset, __be32 info)
0076 {
0077     const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
0078     const struct dccp_hdr *dh;
0079     struct dccp_sock *dp;
0080     struct ipv6_pinfo *np;
0081     struct sock *sk;
0082     int err;
0083     __u64 seq;
0084     struct net *net = dev_net(skb->dev);
0085 
0086     /* Only need dccph_dport & dccph_sport which are the first
0087      * 4 bytes in dccp header.
0088      * Our caller (icmpv6_notify()) already pulled 8 bytes for us.
0089      */
0090     BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
0091     BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
0092     dh = (struct dccp_hdr *)(skb->data + offset);
0093 
0094     sk = __inet6_lookup_established(net, &dccp_hashinfo,
0095                     &hdr->daddr, dh->dccph_dport,
0096                     &hdr->saddr, ntohs(dh->dccph_sport),
0097                     inet6_iif(skb), 0);
0098 
0099     if (!sk) {
0100         __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
0101                   ICMP6_MIB_INERRORS);
0102         return -ENOENT;
0103     }
0104 
0105     if (sk->sk_state == DCCP_TIME_WAIT) {
0106         inet_twsk_put(inet_twsk(sk));
0107         return 0;
0108     }
0109     seq = dccp_hdr_seq(dh);
0110     if (sk->sk_state == DCCP_NEW_SYN_RECV) {
0111         dccp_req_err(sk, seq);
0112         return 0;
0113     }
0114 
0115     bh_lock_sock(sk);
0116     if (sock_owned_by_user(sk))
0117         __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS);
0118 
0119     if (sk->sk_state == DCCP_CLOSED)
0120         goto out;
0121 
0122     dp = dccp_sk(sk);
0123     if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
0124         !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
0125         __NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
0126         goto out;
0127     }
0128 
0129     np = inet6_sk(sk);
0130 
0131     if (type == NDISC_REDIRECT) {
0132         if (!sock_owned_by_user(sk)) {
0133             struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
0134 
0135             if (dst)
0136                 dst->ops->redirect(dst, sk, skb);
0137         }
0138         goto out;
0139     }
0140 
0141     if (type == ICMPV6_PKT_TOOBIG) {
0142         struct dst_entry *dst = NULL;
0143 
0144         if (!ip6_sk_accept_pmtu(sk))
0145             goto out;
0146 
0147         if (sock_owned_by_user(sk))
0148             goto out;
0149         if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
0150             goto out;
0151 
0152         dst = inet6_csk_update_pmtu(sk, ntohl(info));
0153         if (!dst)
0154             goto out;
0155 
0156         if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst))
0157             dccp_sync_mss(sk, dst_mtu(dst));
0158         goto out;
0159     }
0160 
0161     icmpv6_err_convert(type, code, &err);
0162 
0163     /* Might be for an request_sock */
0164     switch (sk->sk_state) {
0165     case DCCP_REQUESTING:
0166     case DCCP_RESPOND:  /* Cannot happen.
0167                    It can, it SYNs are crossed. --ANK */
0168         if (!sock_owned_by_user(sk)) {
0169             __DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
0170             sk->sk_err = err;
0171             /*
0172              * Wake people up to see the error
0173              * (see connect in sock.c)
0174              */
0175             sk_error_report(sk);
0176             dccp_done(sk);
0177         } else
0178             sk->sk_err_soft = err;
0179         goto out;
0180     }
0181 
0182     if (!sock_owned_by_user(sk) && np->recverr) {
0183         sk->sk_err = err;
0184         sk_error_report(sk);
0185     } else
0186         sk->sk_err_soft = err;
0187 
0188 out:
0189     bh_unlock_sock(sk);
0190     sock_put(sk);
0191     return 0;
0192 }
0193 
0194 
0195 static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req)
0196 {
0197     struct inet_request_sock *ireq = inet_rsk(req);
0198     struct ipv6_pinfo *np = inet6_sk(sk);
0199     struct sk_buff *skb;
0200     struct in6_addr *final_p, final;
0201     struct flowi6 fl6;
0202     int err = -1;
0203     struct dst_entry *dst;
0204 
0205     memset(&fl6, 0, sizeof(fl6));
0206     fl6.flowi6_proto = IPPROTO_DCCP;
0207     fl6.daddr = ireq->ir_v6_rmt_addr;
0208     fl6.saddr = ireq->ir_v6_loc_addr;
0209     fl6.flowlabel = 0;
0210     fl6.flowi6_oif = ireq->ir_iif;
0211     fl6.fl6_dport = ireq->ir_rmt_port;
0212     fl6.fl6_sport = htons(ireq->ir_num);
0213     security_req_classify_flow(req, flowi6_to_flowi_common(&fl6));
0214 
0215 
0216     rcu_read_lock();
0217     final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
0218     rcu_read_unlock();
0219 
0220     dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
0221     if (IS_ERR(dst)) {
0222         err = PTR_ERR(dst);
0223         dst = NULL;
0224         goto done;
0225     }
0226 
0227     skb = dccp_make_response(sk, dst, req);
0228     if (skb != NULL) {
0229         struct dccp_hdr *dh = dccp_hdr(skb);
0230         struct ipv6_txoptions *opt;
0231 
0232         dh->dccph_checksum = dccp_v6_csum_finish(skb,
0233                              &ireq->ir_v6_loc_addr,
0234                              &ireq->ir_v6_rmt_addr);
0235         fl6.daddr = ireq->ir_v6_rmt_addr;
0236         rcu_read_lock();
0237         opt = ireq->ipv6_opt;
0238         if (!opt)
0239             opt = rcu_dereference(np->opt);
0240         err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass,
0241                    sk->sk_priority);
0242         rcu_read_unlock();
0243         err = net_xmit_eval(err);
0244     }
0245 
0246 done:
0247     dst_release(dst);
0248     return err;
0249 }
0250 
0251 static void dccp_v6_reqsk_destructor(struct request_sock *req)
0252 {
0253     dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
0254     kfree(inet_rsk(req)->ipv6_opt);
0255     kfree_skb(inet_rsk(req)->pktopts);
0256 }
0257 
0258 static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
0259 {
0260     const struct ipv6hdr *rxip6h;
0261     struct sk_buff *skb;
0262     struct flowi6 fl6;
0263     struct net *net = dev_net(skb_dst(rxskb)->dev);
0264     struct dccp_v6_pernet *pn;
0265     struct sock *ctl_sk;
0266     struct dst_entry *dst;
0267 
0268     if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
0269         return;
0270 
0271     if (!ipv6_unicast_destination(rxskb))
0272         return;
0273 
0274     pn = net_generic(net, dccp_v6_pernet_id);
0275     ctl_sk = pn->v6_ctl_sk;
0276     skb = dccp_ctl_make_reset(ctl_sk, rxskb);
0277     if (skb == NULL)
0278         return;
0279 
0280     rxip6h = ipv6_hdr(rxskb);
0281     dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr,
0282                                 &rxip6h->daddr);
0283 
0284     memset(&fl6, 0, sizeof(fl6));
0285     fl6.daddr = rxip6h->saddr;
0286     fl6.saddr = rxip6h->daddr;
0287 
0288     fl6.flowi6_proto = IPPROTO_DCCP;
0289     fl6.flowi6_oif = inet6_iif(rxskb);
0290     fl6.fl6_dport = dccp_hdr(skb)->dccph_dport;
0291     fl6.fl6_sport = dccp_hdr(skb)->dccph_sport;
0292     security_skb_classify_flow(rxskb, flowi6_to_flowi_common(&fl6));
0293 
0294     /* sk = NULL, but it is safe for now. RST socket required. */
0295     dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL);
0296     if (!IS_ERR(dst)) {
0297         skb_dst_set(skb, dst);
0298         ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0, 0);
0299         DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
0300         DCCP_INC_STATS(DCCP_MIB_OUTRSTS);
0301         return;
0302     }
0303 
0304     kfree_skb(skb);
0305 }
0306 
0307 static struct request_sock_ops dccp6_request_sock_ops = {
0308     .family     = AF_INET6,
0309     .obj_size   = sizeof(struct dccp6_request_sock),
0310     .rtx_syn_ack    = dccp_v6_send_response,
0311     .send_ack   = dccp_reqsk_send_ack,
0312     .destructor = dccp_v6_reqsk_destructor,
0313     .send_reset = dccp_v6_ctl_send_reset,
0314     .syn_ack_timeout = dccp_syn_ack_timeout,
0315 };
0316 
0317 static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
0318 {
0319     struct request_sock *req;
0320     struct dccp_request_sock *dreq;
0321     struct inet_request_sock *ireq;
0322     struct ipv6_pinfo *np = inet6_sk(sk);
0323     const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
0324     struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
0325 
0326     if (skb->protocol == htons(ETH_P_IP))
0327         return dccp_v4_conn_request(sk, skb);
0328 
0329     if (!ipv6_unicast_destination(skb))
0330         return 0;   /* discard, don't send a reset here */
0331 
0332     if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) {
0333         __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS);
0334         return 0;
0335     }
0336 
0337     if (dccp_bad_service_code(sk, service)) {
0338         dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
0339         goto drop;
0340     }
0341     /*
0342      * There are no SYN attacks on IPv6, yet...
0343      */
0344     dcb->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
0345     if (inet_csk_reqsk_queue_is_full(sk))
0346         goto drop;
0347 
0348     if (sk_acceptq_is_full(sk))
0349         goto drop;
0350 
0351     req = inet_reqsk_alloc(&dccp6_request_sock_ops, sk, true);
0352     if (req == NULL)
0353         goto drop;
0354 
0355     if (dccp_reqsk_init(req, dccp_sk(sk), skb))
0356         goto drop_and_free;
0357 
0358     dreq = dccp_rsk(req);
0359     if (dccp_parse_options(sk, dreq, skb))
0360         goto drop_and_free;
0361 
0362     if (security_inet_conn_request(sk, skb, req))
0363         goto drop_and_free;
0364 
0365     ireq = inet_rsk(req);
0366     ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
0367     ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
0368     ireq->ireq_family = AF_INET6;
0369     ireq->ir_mark = inet_request_mark(sk, skb);
0370 
0371     if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) ||
0372         np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
0373         np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
0374         refcount_inc(&skb->users);
0375         ireq->pktopts = skb;
0376     }
0377     ireq->ir_iif = READ_ONCE(sk->sk_bound_dev_if);
0378 
0379     /* So that link locals have meaning */
0380     if (!ireq->ir_iif &&
0381         ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
0382         ireq->ir_iif = inet6_iif(skb);
0383 
0384     /*
0385      * Step 3: Process LISTEN state
0386      *
0387      *   Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
0388      *
0389      * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
0390      */
0391     dreq->dreq_isr     = dcb->dccpd_seq;
0392     dreq->dreq_gsr     = dreq->dreq_isr;
0393     dreq->dreq_iss     = dccp_v6_init_sequence(skb);
0394     dreq->dreq_gss     = dreq->dreq_iss;
0395     dreq->dreq_service = service;
0396 
0397     if (dccp_v6_send_response(sk, req))
0398         goto drop_and_free;
0399 
0400     inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
0401     reqsk_put(req);
0402     return 0;
0403 
0404 drop_and_free:
0405     reqsk_free(req);
0406 drop:
0407     __DCCP_INC_STATS(DCCP_MIB_ATTEMPTFAILS);
0408     return -1;
0409 }
0410 
0411 static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
0412                           struct sk_buff *skb,
0413                           struct request_sock *req,
0414                           struct dst_entry *dst,
0415                           struct request_sock *req_unhash,
0416                           bool *own_req)
0417 {
0418     struct inet_request_sock *ireq = inet_rsk(req);
0419     struct ipv6_pinfo *newnp;
0420     const struct ipv6_pinfo *np = inet6_sk(sk);
0421     struct ipv6_txoptions *opt;
0422     struct inet_sock *newinet;
0423     struct dccp6_sock *newdp6;
0424     struct sock *newsk;
0425 
0426     if (skb->protocol == htons(ETH_P_IP)) {
0427         /*
0428          *  v6 mapped
0429          */
0430         newsk = dccp_v4_request_recv_sock(sk, skb, req, dst,
0431                           req_unhash, own_req);
0432         if (newsk == NULL)
0433             return NULL;
0434 
0435         newdp6 = (struct dccp6_sock *)newsk;
0436         newinet = inet_sk(newsk);
0437         newinet->pinet6 = &newdp6->inet6;
0438         newnp = inet6_sk(newsk);
0439 
0440         memcpy(newnp, np, sizeof(struct ipv6_pinfo));
0441 
0442         newnp->saddr = newsk->sk_v6_rcv_saddr;
0443 
0444         inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
0445         newsk->sk_backlog_rcv = dccp_v4_do_rcv;
0446         newnp->pktoptions  = NULL;
0447         newnp->opt     = NULL;
0448         newnp->ipv6_mc_list = NULL;
0449         newnp->ipv6_ac_list = NULL;
0450         newnp->ipv6_fl_list = NULL;
0451         newnp->mcast_oif   = inet_iif(skb);
0452         newnp->mcast_hops  = ip_hdr(skb)->ttl;
0453 
0454         /*
0455          * No need to charge this sock to the relevant IPv6 refcnt debug socks count
0456          * here, dccp_create_openreq_child now does this for us, see the comment in
0457          * that function for the gory details. -acme
0458          */
0459 
0460         /* It is tricky place. Until this moment IPv4 tcp
0461            worked with IPv6 icsk.icsk_af_ops.
0462            Sync it now.
0463          */
0464         dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
0465 
0466         return newsk;
0467     }
0468 
0469 
0470     if (sk_acceptq_is_full(sk))
0471         goto out_overflow;
0472 
0473     if (!dst) {
0474         struct flowi6 fl6;
0475 
0476         dst = inet6_csk_route_req(sk, &fl6, req, IPPROTO_DCCP);
0477         if (!dst)
0478             goto out;
0479     }
0480 
0481     newsk = dccp_create_openreq_child(sk, req, skb);
0482     if (newsk == NULL)
0483         goto out_nonewsk;
0484 
0485     /*
0486      * No need to charge this sock to the relevant IPv6 refcnt debug socks
0487      * count here, dccp_create_openreq_child now does this for us, see the
0488      * comment in that function for the gory details. -acme
0489      */
0490 
0491     ip6_dst_store(newsk, dst, NULL, NULL);
0492     newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
0493                               NETIF_F_TSO);
0494     newdp6 = (struct dccp6_sock *)newsk;
0495     newinet = inet_sk(newsk);
0496     newinet->pinet6 = &newdp6->inet6;
0497     newnp = inet6_sk(newsk);
0498 
0499     memcpy(newnp, np, sizeof(struct ipv6_pinfo));
0500 
0501     newsk->sk_v6_daddr  = ireq->ir_v6_rmt_addr;
0502     newnp->saddr        = ireq->ir_v6_loc_addr;
0503     newsk->sk_v6_rcv_saddr  = ireq->ir_v6_loc_addr;
0504     newsk->sk_bound_dev_if  = ireq->ir_iif;
0505 
0506     /* Now IPv6 options...
0507 
0508        First: no IPv4 options.
0509      */
0510     newinet->inet_opt = NULL;
0511 
0512     /* Clone RX bits */
0513     newnp->rxopt.all = np->rxopt.all;
0514 
0515     newnp->ipv6_mc_list = NULL;
0516     newnp->ipv6_ac_list = NULL;
0517     newnp->ipv6_fl_list = NULL;
0518     newnp->pktoptions = NULL;
0519     newnp->opt    = NULL;
0520     newnp->mcast_oif  = inet6_iif(skb);
0521     newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
0522 
0523     /*
0524      * Clone native IPv6 options from listening socket (if any)
0525      *
0526      * Yes, keeping reference count would be much more clever, but we make
0527      * one more one thing there: reattach optmem to newsk.
0528      */
0529     opt = ireq->ipv6_opt;
0530     if (!opt)
0531         opt = rcu_dereference(np->opt);
0532     if (opt) {
0533         opt = ipv6_dup_options(newsk, opt);
0534         RCU_INIT_POINTER(newnp->opt, opt);
0535     }
0536     inet_csk(newsk)->icsk_ext_hdr_len = 0;
0537     if (opt)
0538         inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
0539                             opt->opt_flen;
0540 
0541     dccp_sync_mss(newsk, dst_mtu(dst));
0542 
0543     newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
0544     newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
0545 
0546     if (__inet_inherit_port(sk, newsk) < 0) {
0547         inet_csk_prepare_forced_close(newsk);
0548         dccp_done(newsk);
0549         goto out;
0550     }
0551     *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL);
0552     /* Clone pktoptions received with SYN, if we own the req */
0553     if (*own_req && ireq->pktopts) {
0554         newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC);
0555         consume_skb(ireq->pktopts);
0556         ireq->pktopts = NULL;
0557         if (newnp->pktoptions)
0558             skb_set_owner_r(newnp->pktoptions, newsk);
0559     }
0560 
0561     return newsk;
0562 
0563 out_overflow:
0564     __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
0565 out_nonewsk:
0566     dst_release(dst);
0567 out:
0568     __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
0569     return NULL;
0570 }
0571 
0572 /* The socket must have it's spinlock held when we get
0573  * here.
0574  *
0575  * We have a potential double-lock case here, so even when
0576  * doing backlog processing we use the BH locking scheme.
0577  * This is because we cannot sleep with the original spinlock
0578  * held.
0579  */
0580 static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
0581 {
0582     struct ipv6_pinfo *np = inet6_sk(sk);
0583     struct sk_buff *opt_skb = NULL;
0584 
0585     /* Imagine: socket is IPv6. IPv4 packet arrives,
0586        goes to IPv4 receive handler and backlogged.
0587        From backlog it always goes here. Kerboom...
0588        Fortunately, dccp_rcv_established and rcv_established
0589        handle them correctly, but it is not case with
0590        dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
0591      */
0592 
0593     if (skb->protocol == htons(ETH_P_IP))
0594         return dccp_v4_do_rcv(sk, skb);
0595 
0596     if (sk_filter(sk, skb))
0597         goto discard;
0598 
0599     /*
0600      * socket locking is here for SMP purposes as backlog rcv is currently
0601      * called with bh processing disabled.
0602      */
0603 
0604     /* Do Stevens' IPV6_PKTOPTIONS.
0605 
0606        Yes, guys, it is the only place in our code, where we
0607        may make it not affecting IPv4.
0608        The rest of code is protocol independent,
0609        and I do not like idea to uglify IPv4.
0610 
0611        Actually, all the idea behind IPV6_PKTOPTIONS
0612        looks not very well thought. For now we latch
0613        options, received in the last packet, enqueued
0614        by tcp. Feel free to propose better solution.
0615                            --ANK (980728)
0616      */
0617     if (np->rxopt.all)
0618         opt_skb = skb_clone(skb, GFP_ATOMIC);
0619 
0620     if (sk->sk_state == DCCP_OPEN) { /* Fast path */
0621         if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
0622             goto reset;
0623         if (opt_skb)
0624             goto ipv6_pktoptions;
0625         return 0;
0626     }
0627 
0628     /*
0629      *  Step 3: Process LISTEN state
0630      *     If S.state == LISTEN,
0631      *   If P.type == Request or P contains a valid Init Cookie option,
0632      *        (* Must scan the packet's options to check for Init
0633      *       Cookies.  Only Init Cookies are processed here,
0634      *       however; other options are processed in Step 8.  This
0635      *       scan need only be performed if the endpoint uses Init
0636      *       Cookies *)
0637      *        (* Generate a new socket and switch to that socket *)
0638      *        Set S := new socket for this port pair
0639      *        S.state = RESPOND
0640      *        Choose S.ISS (initial seqno) or set from Init Cookies
0641      *        Initialize S.GAR := S.ISS
0642      *        Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
0643      *        Continue with S.state == RESPOND
0644      *        (* A Response packet will be generated in Step 11 *)
0645      *   Otherwise,
0646      *        Generate Reset(No Connection) unless P.type == Reset
0647      *        Drop packet and return
0648      *
0649      * NOTE: the check for the packet types is done in
0650      *   dccp_rcv_state_process
0651      */
0652 
0653     if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
0654         goto reset;
0655     if (opt_skb)
0656         goto ipv6_pktoptions;
0657     return 0;
0658 
0659 reset:
0660     dccp_v6_ctl_send_reset(sk, skb);
0661 discard:
0662     if (opt_skb != NULL)
0663         __kfree_skb(opt_skb);
0664     kfree_skb(skb);
0665     return 0;
0666 
0667 /* Handling IPV6_PKTOPTIONS skb the similar
0668  * way it's done for net/ipv6/tcp_ipv6.c
0669  */
0670 ipv6_pktoptions:
0671     if (!((1 << sk->sk_state) & (DCCPF_CLOSED | DCCPF_LISTEN))) {
0672         if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
0673             np->mcast_oif = inet6_iif(opt_skb);
0674         if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
0675             np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
0676         if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass)
0677             np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
0678         if (np->repflow)
0679             np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
0680         if (ipv6_opt_accepted(sk, opt_skb,
0681                       &DCCP_SKB_CB(opt_skb)->header.h6)) {
0682             skb_set_owner_r(opt_skb, sk);
0683             memmove(IP6CB(opt_skb),
0684                 &DCCP_SKB_CB(opt_skb)->header.h6,
0685                 sizeof(struct inet6_skb_parm));
0686             opt_skb = xchg(&np->pktoptions, opt_skb);
0687         } else {
0688             __kfree_skb(opt_skb);
0689             opt_skb = xchg(&np->pktoptions, NULL);
0690         }
0691     }
0692 
0693     kfree_skb(opt_skb);
0694     return 0;
0695 }
0696 
0697 static int dccp_v6_rcv(struct sk_buff *skb)
0698 {
0699     const struct dccp_hdr *dh;
0700     bool refcounted;
0701     struct sock *sk;
0702     int min_cov;
0703 
0704     /* Step 1: Check header basics */
0705 
0706     if (dccp_invalid_packet(skb))
0707         goto discard_it;
0708 
0709     /* Step 1: If header checksum is incorrect, drop packet and return. */
0710     if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->saddr,
0711                      &ipv6_hdr(skb)->daddr)) {
0712         DCCP_WARN("dropped packet with invalid checksum\n");
0713         goto discard_it;
0714     }
0715 
0716     dh = dccp_hdr(skb);
0717 
0718     DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
0719     DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
0720 
0721     if (dccp_packet_without_ack(skb))
0722         DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
0723     else
0724         DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
0725 
0726 lookup:
0727     sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
0728                     dh->dccph_sport, dh->dccph_dport,
0729                 inet6_iif(skb), 0, &refcounted);
0730     if (!sk) {
0731         dccp_pr_debug("failed to look up flow ID in table and "
0732                   "get corresponding socket\n");
0733         goto no_dccp_socket;
0734     }
0735 
0736     /*
0737      * Step 2:
0738      *  ... or S.state == TIMEWAIT,
0739      *      Generate Reset(No Connection) unless P.type == Reset
0740      *      Drop packet and return
0741      */
0742     if (sk->sk_state == DCCP_TIME_WAIT) {
0743         dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
0744         inet_twsk_put(inet_twsk(sk));
0745         goto no_dccp_socket;
0746     }
0747 
0748     if (sk->sk_state == DCCP_NEW_SYN_RECV) {
0749         struct request_sock *req = inet_reqsk(sk);
0750         struct sock *nsk;
0751 
0752         sk = req->rsk_listener;
0753         if (unlikely(sk->sk_state != DCCP_LISTEN)) {
0754             inet_csk_reqsk_queue_drop_and_put(sk, req);
0755             goto lookup;
0756         }
0757         sock_hold(sk);
0758         refcounted = true;
0759         nsk = dccp_check_req(sk, skb, req);
0760         if (!nsk) {
0761             reqsk_put(req);
0762             goto discard_and_relse;
0763         }
0764         if (nsk == sk) {
0765             reqsk_put(req);
0766         } else if (dccp_child_process(sk, nsk, skb)) {
0767             dccp_v6_ctl_send_reset(sk, skb);
0768             goto discard_and_relse;
0769         } else {
0770             sock_put(sk);
0771             return 0;
0772         }
0773     }
0774     /*
0775      * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
0776      *  o if MinCsCov = 0, only packets with CsCov = 0 are accepted
0777      *  o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
0778      */
0779     min_cov = dccp_sk(sk)->dccps_pcrlen;
0780     if (dh->dccph_cscov  &&  (min_cov == 0 || dh->dccph_cscov < min_cov))  {
0781         dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
0782                   dh->dccph_cscov, min_cov);
0783         /* FIXME: send Data Dropped option (see also dccp_v4_rcv) */
0784         goto discard_and_relse;
0785     }
0786 
0787     if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
0788         goto discard_and_relse;
0789 
0790     return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
0791                 refcounted) ? -1 : 0;
0792 
0793 no_dccp_socket:
0794     if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
0795         goto discard_it;
0796     /*
0797      * Step 2:
0798      *  If no socket ...
0799      *      Generate Reset(No Connection) unless P.type == Reset
0800      *      Drop packet and return
0801      */
0802     if (dh->dccph_type != DCCP_PKT_RESET) {
0803         DCCP_SKB_CB(skb)->dccpd_reset_code =
0804                     DCCP_RESET_CODE_NO_CONNECTION;
0805         dccp_v6_ctl_send_reset(sk, skb);
0806     }
0807 
0808 discard_it:
0809     kfree_skb(skb);
0810     return 0;
0811 
0812 discard_and_relse:
0813     if (refcounted)
0814         sock_put(sk);
0815     goto discard_it;
0816 }
0817 
0818 static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
0819                int addr_len)
0820 {
0821     struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
0822     struct inet_connection_sock *icsk = inet_csk(sk);
0823     struct inet_sock *inet = inet_sk(sk);
0824     struct ipv6_pinfo *np = inet6_sk(sk);
0825     struct dccp_sock *dp = dccp_sk(sk);
0826     struct in6_addr *saddr = NULL, *final_p, final;
0827     struct ipv6_txoptions *opt;
0828     struct flowi6 fl6;
0829     struct dst_entry *dst;
0830     int addr_type;
0831     int err;
0832 
0833     dp->dccps_role = DCCP_ROLE_CLIENT;
0834 
0835     if (addr_len < SIN6_LEN_RFC2133)
0836         return -EINVAL;
0837 
0838     if (usin->sin6_family != AF_INET6)
0839         return -EAFNOSUPPORT;
0840 
0841     memset(&fl6, 0, sizeof(fl6));
0842 
0843     if (np->sndflow) {
0844         fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
0845         IP6_ECN_flow_init(fl6.flowlabel);
0846         if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) {
0847             struct ip6_flowlabel *flowlabel;
0848             flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
0849             if (IS_ERR(flowlabel))
0850                 return -EINVAL;
0851             fl6_sock_release(flowlabel);
0852         }
0853     }
0854     /*
0855      * connect() to INADDR_ANY means loopback (BSD'ism).
0856      */
0857     if (ipv6_addr_any(&usin->sin6_addr))
0858         usin->sin6_addr.s6_addr[15] = 1;
0859 
0860     addr_type = ipv6_addr_type(&usin->sin6_addr);
0861 
0862     if (addr_type & IPV6_ADDR_MULTICAST)
0863         return -ENETUNREACH;
0864 
0865     if (addr_type & IPV6_ADDR_LINKLOCAL) {
0866         if (addr_len >= sizeof(struct sockaddr_in6) &&
0867             usin->sin6_scope_id) {
0868             /* If interface is set while binding, indices
0869              * must coincide.
0870              */
0871             if (sk->sk_bound_dev_if &&
0872                 sk->sk_bound_dev_if != usin->sin6_scope_id)
0873                 return -EINVAL;
0874 
0875             sk->sk_bound_dev_if = usin->sin6_scope_id;
0876         }
0877 
0878         /* Connect to link-local address requires an interface */
0879         if (!sk->sk_bound_dev_if)
0880             return -EINVAL;
0881     }
0882 
0883     sk->sk_v6_daddr = usin->sin6_addr;
0884     np->flow_label = fl6.flowlabel;
0885 
0886     /*
0887      * DCCP over IPv4
0888      */
0889     if (addr_type == IPV6_ADDR_MAPPED) {
0890         u32 exthdrlen = icsk->icsk_ext_hdr_len;
0891         struct sockaddr_in sin;
0892 
0893         SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
0894 
0895         if (ipv6_only_sock(sk))
0896             return -ENETUNREACH;
0897 
0898         sin.sin_family = AF_INET;
0899         sin.sin_port = usin->sin6_port;
0900         sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
0901 
0902         icsk->icsk_af_ops = &dccp_ipv6_mapped;
0903         sk->sk_backlog_rcv = dccp_v4_do_rcv;
0904 
0905         err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
0906         if (err) {
0907             icsk->icsk_ext_hdr_len = exthdrlen;
0908             icsk->icsk_af_ops = &dccp_ipv6_af_ops;
0909             sk->sk_backlog_rcv = dccp_v6_do_rcv;
0910             goto failure;
0911         }
0912         np->saddr = sk->sk_v6_rcv_saddr;
0913         return err;
0914     }
0915 
0916     if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr))
0917         saddr = &sk->sk_v6_rcv_saddr;
0918 
0919     fl6.flowi6_proto = IPPROTO_DCCP;
0920     fl6.daddr = sk->sk_v6_daddr;
0921     fl6.saddr = saddr ? *saddr : np->saddr;
0922     fl6.flowi6_oif = sk->sk_bound_dev_if;
0923     fl6.fl6_dport = usin->sin6_port;
0924     fl6.fl6_sport = inet->inet_sport;
0925     security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
0926 
0927     opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
0928     final_p = fl6_update_dst(&fl6, opt, &final);
0929 
0930     dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
0931     if (IS_ERR(dst)) {
0932         err = PTR_ERR(dst);
0933         goto failure;
0934     }
0935 
0936     if (saddr == NULL) {
0937         saddr = &fl6.saddr;
0938         sk->sk_v6_rcv_saddr = *saddr;
0939     }
0940 
0941     /* set the source address */
0942     np->saddr = *saddr;
0943     inet->inet_rcv_saddr = LOOPBACK4_IPV6;
0944 
0945     ip6_dst_store(sk, dst, NULL, NULL);
0946 
0947     icsk->icsk_ext_hdr_len = 0;
0948     if (opt)
0949         icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
0950 
0951     inet->inet_dport = usin->sin6_port;
0952 
0953     dccp_set_state(sk, DCCP_REQUESTING);
0954     err = inet6_hash_connect(&dccp_death_row, sk);
0955     if (err)
0956         goto late_failure;
0957 
0958     dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
0959                               sk->sk_v6_daddr.s6_addr32,
0960                               inet->inet_sport,
0961                               inet->inet_dport);
0962     err = dccp_connect(sk);
0963     if (err)
0964         goto late_failure;
0965 
0966     return 0;
0967 
0968 late_failure:
0969     dccp_set_state(sk, DCCP_CLOSED);
0970     __sk_dst_reset(sk);
0971 failure:
0972     inet->inet_dport = 0;
0973     sk->sk_route_caps = 0;
0974     return err;
0975 }
0976 
0977 static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
0978     .queue_xmit    = inet6_csk_xmit,
0979     .send_check    = dccp_v6_send_check,
0980     .rebuild_header    = inet6_sk_rebuild_header,
0981     .conn_request      = dccp_v6_conn_request,
0982     .syn_recv_sock     = dccp_v6_request_recv_sock,
0983     .net_header_len    = sizeof(struct ipv6hdr),
0984     .setsockopt    = ipv6_setsockopt,
0985     .getsockopt    = ipv6_getsockopt,
0986     .addr2sockaddr     = inet6_csk_addr2sockaddr,
0987     .sockaddr_len      = sizeof(struct sockaddr_in6),
0988 };
0989 
0990 /*
0991  *  DCCP over IPv4 via INET6 API
0992  */
0993 static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
0994     .queue_xmit    = ip_queue_xmit,
0995     .send_check    = dccp_v4_send_check,
0996     .rebuild_header    = inet_sk_rebuild_header,
0997     .conn_request      = dccp_v6_conn_request,
0998     .syn_recv_sock     = dccp_v6_request_recv_sock,
0999     .net_header_len    = sizeof(struct iphdr),
1000     .setsockopt    = ipv6_setsockopt,
1001     .getsockopt    = ipv6_getsockopt,
1002     .addr2sockaddr     = inet6_csk_addr2sockaddr,
1003     .sockaddr_len      = sizeof(struct sockaddr_in6),
1004 };
1005 
1006 /* NOTE: A lot of things set to zero explicitly by call to
1007  *       sk_alloc() so need not be done here.
1008  */
1009 static int dccp_v6_init_sock(struct sock *sk)
1010 {
1011     static __u8 dccp_v6_ctl_sock_initialized;
1012     int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
1013 
1014     if (err == 0) {
1015         if (unlikely(!dccp_v6_ctl_sock_initialized))
1016             dccp_v6_ctl_sock_initialized = 1;
1017         inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1018     }
1019 
1020     return err;
1021 }
1022 
1023 static void dccp_v6_destroy_sock(struct sock *sk)
1024 {
1025     dccp_destroy_sock(sk);
1026     inet6_destroy_sock(sk);
1027 }
1028 
1029 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
1030     .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
1031 };
1032 
1033 static struct proto dccp_v6_prot = {
1034     .name          = "DCCPv6",
1035     .owner         = THIS_MODULE,
1036     .close         = dccp_close,
1037     .connect       = dccp_v6_connect,
1038     .disconnect    = dccp_disconnect,
1039     .ioctl         = dccp_ioctl,
1040     .init          = dccp_v6_init_sock,
1041     .setsockopt    = dccp_setsockopt,
1042     .getsockopt    = dccp_getsockopt,
1043     .sendmsg       = dccp_sendmsg,
1044     .recvmsg       = dccp_recvmsg,
1045     .backlog_rcv       = dccp_v6_do_rcv,
1046     .hash          = inet6_hash,
1047     .unhash        = inet_unhash,
1048     .accept        = inet_csk_accept,
1049     .get_port      = inet_csk_get_port,
1050     .shutdown      = dccp_shutdown,
1051     .destroy       = dccp_v6_destroy_sock,
1052     .orphan_count      = &dccp_orphan_count,
1053     .max_header    = MAX_DCCP_HEADER,
1054     .obj_size      = sizeof(struct dccp6_sock),
1055     .slab_flags    = SLAB_TYPESAFE_BY_RCU,
1056     .rsk_prot      = &dccp6_request_sock_ops,
1057     .twsk_prot     = &dccp6_timewait_sock_ops,
1058     .h.hashinfo    = &dccp_hashinfo,
1059 };
1060 
1061 static const struct inet6_protocol dccp_v6_protocol = {
1062     .handler    = dccp_v6_rcv,
1063     .err_handler    = dccp_v6_err,
1064     .flags      = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
1065 };
1066 
1067 static const struct proto_ops inet6_dccp_ops = {
1068     .family        = PF_INET6,
1069     .owner         = THIS_MODULE,
1070     .release       = inet6_release,
1071     .bind          = inet6_bind,
1072     .connect       = inet_stream_connect,
1073     .socketpair    = sock_no_socketpair,
1074     .accept        = inet_accept,
1075     .getname       = inet6_getname,
1076     .poll          = dccp_poll,
1077     .ioctl         = inet6_ioctl,
1078     .gettstamp     = sock_gettstamp,
1079     .listen        = inet_dccp_listen,
1080     .shutdown      = inet_shutdown,
1081     .setsockopt    = sock_common_setsockopt,
1082     .getsockopt    = sock_common_getsockopt,
1083     .sendmsg       = inet_sendmsg,
1084     .recvmsg       = sock_common_recvmsg,
1085     .mmap          = sock_no_mmap,
1086     .sendpage      = sock_no_sendpage,
1087 #ifdef CONFIG_COMPAT
1088     .compat_ioctl      = inet6_compat_ioctl,
1089 #endif
1090 };
1091 
1092 static struct inet_protosw dccp_v6_protosw = {
1093     .type       = SOCK_DCCP,
1094     .protocol   = IPPROTO_DCCP,
1095     .prot       = &dccp_v6_prot,
1096     .ops        = &inet6_dccp_ops,
1097     .flags      = INET_PROTOSW_ICSK,
1098 };
1099 
1100 static int __net_init dccp_v6_init_net(struct net *net)
1101 {
1102     struct dccp_v6_pernet *pn = net_generic(net, dccp_v6_pernet_id);
1103 
1104     if (dccp_hashinfo.bhash == NULL)
1105         return -ESOCKTNOSUPPORT;
1106 
1107     return inet_ctl_sock_create(&pn->v6_ctl_sk, PF_INET6,
1108                     SOCK_DCCP, IPPROTO_DCCP, net);
1109 }
1110 
1111 static void __net_exit dccp_v6_exit_net(struct net *net)
1112 {
1113     struct dccp_v6_pernet *pn = net_generic(net, dccp_v6_pernet_id);
1114 
1115     inet_ctl_sock_destroy(pn->v6_ctl_sk);
1116 }
1117 
1118 static void __net_exit dccp_v6_exit_batch(struct list_head *net_exit_list)
1119 {
1120     inet_twsk_purge(&dccp_hashinfo, AF_INET6);
1121 }
1122 
1123 static struct pernet_operations dccp_v6_ops = {
1124     .init   = dccp_v6_init_net,
1125     .exit   = dccp_v6_exit_net,
1126     .exit_batch = dccp_v6_exit_batch,
1127     .id = &dccp_v6_pernet_id,
1128     .size   = sizeof(struct dccp_v6_pernet),
1129 };
1130 
1131 static int __init dccp_v6_init(void)
1132 {
1133     int err = proto_register(&dccp_v6_prot, 1);
1134 
1135     if (err)
1136         goto out;
1137 
1138     inet6_register_protosw(&dccp_v6_protosw);
1139 
1140     err = register_pernet_subsys(&dccp_v6_ops);
1141     if (err)
1142         goto out_destroy_ctl_sock;
1143 
1144     err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1145     if (err)
1146         goto out_unregister_proto;
1147 
1148 out:
1149     return err;
1150 out_unregister_proto:
1151     unregister_pernet_subsys(&dccp_v6_ops);
1152 out_destroy_ctl_sock:
1153     inet6_unregister_protosw(&dccp_v6_protosw);
1154     proto_unregister(&dccp_v6_prot);
1155     goto out;
1156 }
1157 
1158 static void __exit dccp_v6_exit(void)
1159 {
1160     inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1161     unregister_pernet_subsys(&dccp_v6_ops);
1162     inet6_unregister_protosw(&dccp_v6_protosw);
1163     proto_unregister(&dccp_v6_prot);
1164 }
1165 
1166 module_init(dccp_v6_init);
1167 module_exit(dccp_v6_exit);
1168 
1169 /*
1170  * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
1171  * values directly, Also cover the case where the protocol is not specified,
1172  * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
1173  */
1174 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
1175 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
1176 MODULE_LICENSE("GPL");
1177 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
1178 MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");