source: src/linux/universal/linux-3.18/net/dccp/ipv6.c @ 31869

Last change on this file since 31869 was 31869, checked in by brainslayer, 6 weeks ago

update

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