~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/ipv6/tcp_ipv6.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      TCP over IPv6
  3  *      Linux INET6 implementation 
  4  *
  5  *      Authors:
  6  *      Pedro Roque             <roque@di.fc.ul.pt>     
  7  *
  8  *      $Id: tcp_ipv6.c,v 1.128 2000/12/08 17:15:54 davem Exp $
  9  *
 10  *      Based on: 
 11  *      linux/net/ipv4/tcp.c
 12  *      linux/net/ipv4/tcp_input.c
 13  *      linux/net/ipv4/tcp_output.c
 14  *
 15  *      Fixes:
 16  *      Hideaki YOSHIFUJI       :       sin6_scope_id support
 17  *
 18  *      This program is free software; you can redistribute it and/or
 19  *      modify it under the terms of the GNU General Public License
 20  *      as published by the Free Software Foundation; either version
 21  *      2 of the License, or (at your option) any later version.
 22  */
 23 
 24 #define __NO_VERSION__
 25 #include <linux/module.h>
 26 #include <linux/config.h>
 27 #include <linux/errno.h>
 28 #include <linux/types.h>
 29 #include <linux/socket.h>
 30 #include <linux/sockios.h>
 31 #include <linux/net.h>
 32 #include <linux/sched.h>
 33 #include <linux/in.h>
 34 #include <linux/in6.h>
 35 #include <linux/netdevice.h>
 36 #include <linux/init.h>
 37 #include <linux/ipsec.h>
 38 
 39 #include <linux/ipv6.h>
 40 #include <linux/icmpv6.h>
 41 #include <linux/random.h>
 42 
 43 #include <net/tcp.h>
 44 #include <net/ndisc.h>
 45 #include <net/ipv6.h>
 46 #include <net/transp_v6.h>
 47 #include <net/addrconf.h>
 48 #include <net/ip6_route.h>
 49 #include <net/inet_ecn.h>
 50 
 51 #include <asm/uaccess.h>
 52 
 53 static void     tcp_v6_send_reset(struct sk_buff *skb);
 54 static void     tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req);
 55 static void     tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
 56                                   struct sk_buff *skb);
 57 
 58 static int      tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
 59 static int      tcp_v6_xmit(struct sk_buff *skb);
 60 
 61 static struct tcp_func ipv6_mapped;
 62 static struct tcp_func ipv6_specific;
 63 
 64 /* I have no idea if this is a good hash for v6 or not. -DaveM */
 65 static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport,
 66                                     struct in6_addr *faddr, u16 fport)
 67 {
 68         int hashent = (lport ^ fport);
 69 
 70         hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
 71         hashent ^= hashent>>16;
 72         hashent ^= hashent>>8;
 73         return (hashent & (tcp_ehash_size - 1));
 74 }
 75 
 76 static __inline__ int tcp_v6_sk_hashfn(struct sock *sk)
 77 {
 78         struct in6_addr *laddr = &sk->net_pinfo.af_inet6.rcv_saddr;
 79         struct in6_addr *faddr = &sk->net_pinfo.af_inet6.daddr;
 80         __u16 lport = sk->num;
 81         __u16 fport = sk->dport;
 82         return tcp_v6_hashfn(laddr, lport, faddr, fport);
 83 }
 84 
 85 /* Grrr, addr_type already calculated by caller, but I don't want
 86  * to add some silly "cookie" argument to this method just for that.
 87  * But it doesn't matter, the recalculation is in the rarest path
 88  * this function ever takes.
 89  */
 90 static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 91 {
 92         struct tcp_bind_hashbucket *head;
 93         struct tcp_bind_bucket *tb;
 94         int ret;
 95 
 96         local_bh_disable();
 97         if (snum == 0) {
 98                 int low = sysctl_local_port_range[0];
 99                 int high = sysctl_local_port_range[1];
100                 int remaining = (high - low) + 1;
101                 int rover;
102 
103                 spin_lock(&tcp_portalloc_lock);
104                 rover = tcp_port_rover;
105                 do {    rover++;
106                         if ((rover < low) || (rover > high))
107                                 rover = low;
108                         head = &tcp_bhash[tcp_bhashfn(rover)];
109                         spin_lock(&head->lock);
110                         for (tb = head->chain; tb; tb = tb->next)
111                                 if (tb->port == rover)
112                                         goto next;
113                         break;
114                 next:
115                         spin_unlock(&head->lock);
116                 } while (--remaining > 0);
117                 tcp_port_rover = rover;
118                 spin_unlock(&tcp_portalloc_lock);
119 
120                 /* Exhausted local port range during search? */
121                 ret = 1;
122                 if (remaining <= 0)
123                         goto fail;
124 
125                 /* OK, here is the one we will use. */
126                 snum = rover;
127                 tb = NULL;
128         } else {
129                 head = &tcp_bhash[tcp_bhashfn(snum)];
130                 spin_lock(&head->lock);
131                 for (tb = head->chain; tb != NULL; tb = tb->next)
132                         if (tb->port == snum)
133                                 break;
134         }
135         if (tb != NULL && tb->owners != NULL) {
136                 if (tb->fastreuse != 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
137                         goto success;
138                 } else {
139                         struct sock *sk2 = tb->owners;
140                         int sk_reuse = sk->reuse;
141                         int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
142 
143                         /* We must walk the whole port owner list in this case. -DaveM */
144                         for( ; sk2 != NULL; sk2 = sk2->bind_next) {
145                                 if (sk != sk2 &&
146                                     sk->bound_dev_if == sk2->bound_dev_if) {
147                                         if (!sk_reuse   ||
148                                             !sk2->reuse ||
149                                             sk2->state == TCP_LISTEN) {
150                                                 /* NOTE: IPv6 tw bucket have different format */
151                                                 if (!sk2->rcv_saddr     ||
152                                                     addr_type == IPV6_ADDR_ANY ||
153                                                     !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
154                                                                    sk2->state != TCP_TIME_WAIT ?
155                                                                    &sk2->net_pinfo.af_inet6.rcv_saddr :
156                                                                    &((struct tcp_tw_bucket*)sk)->v6_rcv_saddr) ||
157                                                     (addr_type==IPV6_ADDR_MAPPED && sk2->family==AF_INET &&
158                                                      sk->rcv_saddr==sk2->rcv_saddr))
159                                                         break;
160                                         }
161                                 }
162                         }
163                         /* If we found a conflict, fail. */
164                         ret = 1;
165                         if (sk2 != NULL)
166                                 goto fail_unlock;
167                 }
168         }
169         ret = 1;
170         if (tb == NULL &&
171             (tb = tcp_bucket_create(head, snum)) == NULL)
172                         goto fail_unlock;
173         if (tb->owners == NULL) {
174                 if (sk->reuse && sk->state != TCP_LISTEN)
175                         tb->fastreuse = 1;
176                 else
177                         tb->fastreuse = 0;
178         } else if (tb->fastreuse &&
179                    ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
180                 tb->fastreuse = 0;
181 
182 success:
183         sk->num = snum;
184         if (sk->prev == NULL) {
185                 if ((sk->bind_next = tb->owners) != NULL)
186                         tb->owners->bind_pprev = &sk->bind_next;
187                 tb->owners = sk;
188                 sk->bind_pprev = &tb->owners;
189                 sk->prev = (struct sock *) tb;
190         } else {
191                 BUG_TRAP(sk->prev == (struct sock *) tb);
192         }
193         ret = 0;
194 
195 fail_unlock:
196         spin_unlock(&head->lock);
197 fail:
198         local_bh_enable();
199         return ret;
200 }
201 
202 static __inline__ void __tcp_v6_hash(struct sock *sk)
203 {
204         struct sock **skp;
205         rwlock_t *lock;
206 
207         BUG_TRAP(sk->pprev==NULL);
208 
209         if(sk->state == TCP_LISTEN) {
210                 skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
211                 lock = &tcp_lhash_lock;
212                 tcp_listen_wlock();
213         } else {
214                 skp = &tcp_ehash[(sk->hashent = tcp_v6_sk_hashfn(sk))].chain;
215                 lock = &tcp_ehash[sk->hashent].lock;
216                 write_lock(lock);
217         }
218 
219         if((sk->next = *skp) != NULL)
220                 (*skp)->pprev = &sk->next;
221         *skp = sk;
222         sk->pprev = skp;
223         sock_prot_inc_use(sk->prot);
224         write_unlock(lock);
225 }
226 
227 
228 static void tcp_v6_hash(struct sock *sk)
229 {
230         if(sk->state != TCP_CLOSE) {
231                 if (sk->tp_pinfo.af_tcp.af_specific == &ipv6_mapped) {
232                         tcp_prot.hash(sk);
233                         return;
234                 }
235                 local_bh_disable();
236                 __tcp_v6_hash(sk);
237                 local_bh_enable();
238         }
239 }
240 
241 static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum, int dif)
242 {
243         struct sock *sk;
244         struct sock *result = NULL;
245         int score, hiscore;
246 
247         hiscore=0;
248         read_lock(&tcp_lhash_lock);
249         sk = tcp_listening_hash[tcp_lhashfn(hnum)];
250         for(; sk; sk = sk->next) {
251                 if((sk->num == hnum) && (sk->family == PF_INET6)) {
252                         struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
253                         
254                         score = 1;
255                         if(!ipv6_addr_any(&np->rcv_saddr)) {
256                                 if(ipv6_addr_cmp(&np->rcv_saddr, daddr))
257                                         continue;
258                                 score++;
259                         }
260                         if (sk->bound_dev_if) {
261                                 if (sk->bound_dev_if != dif)
262                                         continue;
263                                 score++;
264                         }
265                         if (score == 3) {
266                                 result = sk;
267                                 break;
268                         }
269                         if (score > hiscore) {
270                                 hiscore = score;
271                                 result = sk;
272                         }
273                 }
274         }
275         if (result)
276                 sock_hold(result);
277         read_unlock(&tcp_lhash_lock);
278         return result;
279 }
280 
281 /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
282  * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
283  *
284  * The sockhash lock must be held as a reader here.
285  */
286 
287 static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport,
288                                                        struct in6_addr *daddr, u16 hnum,
289                                                        int dif)
290 {
291         struct tcp_ehash_bucket *head;
292         struct sock *sk;
293         __u32 ports = TCP_COMBINED_PORTS(sport, hnum);
294         int hash;
295 
296         /* Optimize here for direct hit, only listening connections can
297          * have wildcards anyways.
298          */
299         hash = tcp_v6_hashfn(daddr, hnum, saddr, sport);
300         head = &tcp_ehash[hash];
301         read_lock(&head->lock);
302         for(sk = head->chain; sk; sk = sk->next) {
303                 /* For IPV6 do the cheaper port and family tests first. */
304                 if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif))
305                         goto hit; /* You sunk my battleship! */
306         }
307         /* Must check for a TIME_WAIT'er before going to listener hash. */
308         for(sk = (head + tcp_ehash_size)->chain; sk; sk = sk->next) {
309                 if(*((__u32 *)&(sk->dport))     == ports        &&
310                    sk->family                   == PF_INET6) {
311                         struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
312                         if(!ipv6_addr_cmp(&tw->v6_daddr, saddr) &&
313                            !ipv6_addr_cmp(&tw->v6_rcv_saddr, daddr) &&
314                            (!sk->bound_dev_if || sk->bound_dev_if == dif))
315                                 goto hit;
316                 }
317         }
318         read_unlock(&head->lock);
319         return NULL;
320 
321 hit:
322         sock_hold(sk);
323         read_unlock(&head->lock);
324         return sk;
325 }
326 
327 
328 static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
329                                            struct in6_addr *daddr, u16 hnum,
330                                            int dif)
331 {
332         struct sock *sk;
333 
334         sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif);
335 
336         if (sk)
337                 return sk;
338 
339         return tcp_v6_lookup_listener(daddr, hnum, dif);
340 }
341 
342 #define tcp_v6_lookup(sa, sp, da, dp, dif) \
343 ({      struct sock *___sk; \
344         local_bh_disable(); \
345         ___sk = __tcp_v6_lookup((sa),(sp),(da),ntohs(dp),(dif)); \
346         local_bh_enable(); \
347         ___sk; \
348 })
349 
350 
351 /*
352  * Open request hash tables.
353  */
354 
355 static __inline__ unsigned tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport)
356 {
357         unsigned h = raddr->s6_addr32[3] ^ rport;
358         h ^= h>>16;
359         h ^= h>>8;
360         return h&(TCP_SYNQ_HSIZE-1);
361 }
362 
363 static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
364                                               struct ipv6hdr *ip6h,
365                                               struct tcphdr *th,
366                                               int iif,
367                                               struct open_request ***prevp)
368 {
369         struct tcp_listen_opt *lopt = tp->listen_opt;
370         struct open_request *req, **prev;  
371         __u16 rport = th->source;
372 
373         for (prev = &lopt->syn_table[tcp_v6_synq_hash(&ip6h->saddr, rport)];
374              (req = *prev) != NULL;
375              prev = &req->dl_next) {
376                 if (req->rmt_port == rport &&
377                     req->class->family == AF_INET6 &&
378                     !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) &&
379                     !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) &&
380                     (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) {
381                         BUG_TRAP(req->sk == NULL);
382                         *prevp = prev;
383                         return req;
384                 }
385         }
386 
387         return NULL;
388 }
389 
390 static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
391                                    struct in6_addr *saddr, 
392                                    struct in6_addr *daddr, 
393                                    unsigned long base)
394 {
395         return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
396 }
397 
398 static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
399 {
400         if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
401                 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
402                                                     skb->nh.ipv6h->saddr.s6_addr32,
403                                                     skb->h.th->dest,
404                                                     skb->h.th->source);
405         } else {
406                 return secure_tcp_sequence_number(skb->nh.iph->daddr,
407                                                   skb->nh.iph->saddr,
408                                                   skb->h.th->dest,
409                                                   skb->h.th->source);
410         }
411 }
412 
413 static int tcp_v6_check_established(struct sock *sk)
414 {
415         struct in6_addr *daddr = &sk->net_pinfo.af_inet6.rcv_saddr;
416         struct in6_addr *saddr = &sk->net_pinfo.af_inet6.daddr;
417         int dif = sk->bound_dev_if;
418         u32 ports = TCP_COMBINED_PORTS(sk->dport, sk->num);
419         int hash = tcp_v6_hashfn(daddr, sk->num, saddr, sk->dport);
420         struct tcp_ehash_bucket *head = &tcp_ehash[hash];
421         struct sock *sk2, **skp;
422         struct tcp_tw_bucket *tw;
423 
424         write_lock(&head->lock);
425 
426         for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp)!=NULL; skp = &sk2->next) {
427                 tw = (struct tcp_tw_bucket*)sk2;
428 
429                 if(*((__u32 *)&(sk2->dport))    == ports        &&
430                    sk2->family                  == PF_INET6     &&
431                    !ipv6_addr_cmp(&tw->v6_daddr, saddr)         &&
432                    !ipv6_addr_cmp(&tw->v6_rcv_saddr, daddr)     &&
433                    sk2->bound_dev_if == sk->bound_dev_if) {
434                         struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
435 
436                         if (tw->ts_recent_stamp) {
437                                 /* See comment in tcp_ipv4.c */
438                                 if ((tp->write_seq = tw->snd_nxt+65535+2) == 0)
439                                         tp->write_seq = 1;
440                                 tp->ts_recent = tw->ts_recent;
441                                 tp->ts_recent_stamp = tw->ts_recent_stamp;
442                                 sock_hold(sk2);
443                                 skp = &head->chain;
444                                 goto unique;
445                         } else
446                                 goto not_unique;
447                 }
448         }
449         tw = NULL;
450 
451         for(skp = &head->chain; (sk2=*skp)!=NULL; skp = &sk2->next) {
452                 if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif))
453                         goto not_unique;
454         }
455 
456 unique:
457         BUG_TRAP(sk->pprev==NULL);
458         if ((sk->next = *skp) != NULL)
459                 (*skp)->pprev = &sk->next;
460 
461         *skp = sk;
462         sk->pprev = skp;
463         sk->hashent = hash;
464         sock_prot_inc_use(sk->prot);
465         write_unlock_bh(&head->lock);
466 
467         if (tw) {
468                 /* Silly. Should hash-dance instead... */
469                 local_bh_disable();
470                 tcp_tw_deschedule(tw);
471                 tcp_timewait_kill(tw);
472                 NET_INC_STATS_BH(TimeWaitRecycled);
473                 local_bh_enable();
474 
475                 tcp_tw_put(tw);
476         }
477         return 0;
478 
479 not_unique:
480         write_unlock_bh(&head->lock);
481         return -EADDRNOTAVAIL;
482 }
483 
484 static int tcp_v6_hash_connecting(struct sock *sk)
485 {
486         unsigned short snum = sk->num;
487         struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(snum)];
488         struct tcp_bind_bucket *tb = head->chain;
489 
490         spin_lock_bh(&head->lock);
491 
492         if (tb->owners == sk && sk->bind_next == NULL) {
493                 __tcp_v6_hash(sk);
494                 spin_unlock_bh(&head->lock);
495                 return 0;
496         } else {
497                 spin_unlock_bh(&head->lock);
498                 return tcp_v6_check_established(sk);
499         }
500 }
501 
502 static __inline__ int tcp_v6_iif(struct sk_buff *skb)
503 {
504         struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
505         return opt->iif;
506 }
507 
508 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
509                           int addr_len)
510 {
511         struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
512         struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
513         struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
514         struct in6_addr *saddr = NULL;
515         struct in6_addr saddr_buf;
516         struct flowi fl;
517         struct dst_entry *dst;
518         struct sk_buff *buff;
519         int addr_type;
520         int err;
521 
522         if (addr_len < SIN6_LEN_RFC2133) 
523                 return -EINVAL;
524 
525         if (usin->sin6_family != AF_INET6) 
526                 return(-EAFNOSUPPORT);
527 
528         fl.fl6_flowlabel = 0;
529         if (np->sndflow) {
530                 fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
531                 IP6_ECN_flow_init(fl.fl6_flowlabel);
532                 if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
533                         struct ip6_flowlabel *flowlabel;
534                         flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
535                         if (flowlabel == NULL)
536                                 return -EINVAL;
537                         ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
538                         fl6_sock_release(flowlabel);
539                 }
540         }
541 
542         /*
543          *      connect() to INADDR_ANY means loopback (BSD'ism).
544          */
545         
546         if(ipv6_addr_any(&usin->sin6_addr))
547                 usin->sin6_addr.s6_addr[15] = 0x1; 
548 
549         addr_type = ipv6_addr_type(&usin->sin6_addr);
550 
551         if(addr_type & IPV6_ADDR_MULTICAST)
552                 return -ENETUNREACH;
553 
554         if (addr_type&IPV6_ADDR_LINKLOCAL) {
555                 if (addr_len >= sizeof(struct sockaddr_in6) &&
556                     usin->sin6_scope_id) {
557                         /* If interface is set while binding, indices
558                          * must coincide.
559                          */
560                         if (sk->bound_dev_if &&
561                             sk->bound_dev_if != usin->sin6_scope_id)
562                                 return -EINVAL;
563 
564                         sk->bound_dev_if = usin->sin6_scope_id;
565                 }
566 
567                 /* Connect to link-local address requires an interface */
568                 if (sk->bound_dev_if == 0)
569                         return -EINVAL;
570         }
571 
572         if (tp->ts_recent_stamp && ipv6_addr_cmp(&np->daddr, &usin->sin6_addr)) {
573                 tp->ts_recent = 0;
574                 tp->ts_recent_stamp = 0;
575                 tp->write_seq = 0;
576         }
577 
578         ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
579         np->flow_label = fl.fl6_flowlabel;
580 
581         /*
582          *      TCP over IPv4
583          */
584 
585         if (addr_type == IPV6_ADDR_MAPPED) {
586                 u32 exthdrlen = tp->ext_header_len;
587                 struct sockaddr_in sin;
588 
589                 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
590 
591                 sin.sin_family = AF_INET;
592                 sin.sin_port = usin->sin6_port;
593                 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
594 
595                 sk->tp_pinfo.af_tcp.af_specific = &ipv6_mapped;
596                 sk->backlog_rcv = tcp_v4_do_rcv;
597 
598                 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
599 
600                 if (err) {
601                         tp->ext_header_len = exthdrlen;
602                         sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific;
603                         sk->backlog_rcv = tcp_v6_do_rcv;
604                         goto failure;
605                 } else {
606                         ipv6_addr_set(&np->saddr, 0, 0, __constant_htonl(0x0000FFFF),
607                                       sk->saddr);
608                         ipv6_addr_set(&np->rcv_saddr, 0, 0, __constant_htonl(0x0000FFFF),
609                                       sk->rcv_saddr);
610                 }
611 
612                 return err;
613         }
614 
615         if (!ipv6_addr_any(&np->rcv_saddr))
616                 saddr = &np->rcv_saddr;
617 
618         fl.proto = IPPROTO_TCP;
619         fl.fl6_dst = &np->daddr;
620         fl.fl6_src = saddr;
621         fl.oif = sk->bound_dev_if;
622         fl.uli_u.ports.dport = usin->sin6_port;
623         fl.uli_u.ports.sport = sk->sport;
624 
625         if (np->opt && np->opt->srcrt) {
626                 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
627                 fl.nl_u.ip6_u.daddr = rt0->addr;
628         }
629 
630         dst = ip6_route_output(sk, &fl);
631 
632         if ((err = dst->error) != 0) {
633                 dst_release(dst);
634                 goto failure;
635         }
636 
637         ip6_dst_store(sk, dst, NULL);
638 
639         if (saddr == NULL) {
640                 err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
641                 if (err)
642                         goto failure;
643 
644                 saddr = &saddr_buf;
645         }
646 
647         /* set the source address */
648         ipv6_addr_copy(&np->rcv_saddr, saddr);
649         ipv6_addr_copy(&np->saddr, saddr);
650         sk->rcv_saddr= LOOPBACK4_IPV6;
651 
652         tp->ext_header_len = 0;
653         if (np->opt)
654                 tp->ext_header_len = np->opt->opt_flen+np->opt->opt_nflen;
655         tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
656 
657         err = -ENOBUFS;
658         buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_KERNEL);
659 
660         if (buff == NULL)
661                 goto failure;
662 
663         sk->dport = usin->sin6_port;
664 
665         /*
666          *      Init variables
667          */
668 
669         if (!tp->write_seq)
670                 tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
671                                                              np->daddr.s6_addr32,
672                                                              sk->sport, sk->dport);
673 
674         err = tcp_connect(sk, buff);
675         if (err == 0)
676                 return 0;
677 
678 failure:
679         __sk_dst_reset(sk);
680         sk->dport = 0;
681         return err;
682 }
683 
684 void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
685                 struct inet6_skb_parm *opt,
686                 int type, int code, unsigned char *header, __u32 info)
687 {
688         struct in6_addr *saddr = &hdr->saddr;
689         struct in6_addr *daddr = &hdr->daddr;
690         struct tcphdr *th = (struct tcphdr *)header;
691         struct ipv6_pinfo *np;
692         struct sock *sk;
693         int err;
694         struct tcp_opt *tp; 
695         __u32 seq;
696 
697         if (header + 8 > skb->tail)
698                 return;
699 
700         sk = tcp_v6_lookup(daddr, th->dest, saddr, th->source, skb->dev->ifindex);
701 
702         if (sk == NULL) {
703                 ICMP6_INC_STATS_BH(Icmp6InErrors);
704                 return;
705         }
706 
707         if (sk->state == TCP_TIME_WAIT) {
708                 tcp_tw_put((struct tcp_tw_bucket*)sk);
709                 return;
710         }
711 
712         bh_lock_sock(sk);
713         if (sk->lock.users)
714                 NET_INC_STATS_BH(LockDroppedIcmps);
715 
716         if (sk->state == TCP_CLOSE)
717                 goto out;
718 
719         tp = &sk->tp_pinfo.af_tcp;
720         seq = ntohl(th->seq); 
721         if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) {
722                 NET_INC_STATS_BH(OutOfWindowIcmps);
723                 goto out;
724         }
725 
726         np = &sk->net_pinfo.af_inet6;
727 
728         if (type == ICMPV6_PKT_TOOBIG) {
729                 struct dst_entry *dst = NULL;
730 
731                 if (sk->lock.users)
732                         goto out;
733                 if ((1<<sk->state)&(TCPF_LISTEN|TCPF_CLOSE))
734                         goto out;
735 
736                 /* icmp should have updated the destination cache entry */
737                 dst = __sk_dst_check(sk, np->dst_cookie);
738 
739                 if (dst == NULL) {
740                         struct flowi fl;
741 
742                         /* BUGGG_FUTURE: Again, it is not clear how
743                            to handle rthdr case. Ignore this complexity
744                            for now.
745                          */
746                         fl.proto = IPPROTO_TCP;
747                         fl.nl_u.ip6_u.daddr = &np->daddr;
748                         fl.nl_u.ip6_u.saddr = &np->saddr;
749                         fl.oif = sk->bound_dev_if;
750                         fl.uli_u.ports.dport = sk->dport;
751                         fl.uli_u.ports.sport = sk->sport;
752 
753                         dst = ip6_route_output(sk, &fl);
754                 } else
755                         dst_clone(dst);
756 
757                 if (dst->error) {
758                         sk->err_soft = -dst->error;
759                 } else if (tp->pmtu_cookie > dst->pmtu) {
760                         tcp_sync_mss(sk, dst->pmtu);
761                         tcp_simple_retransmit(sk);
762                 } /* else let the usual retransmit timer handle it */
763                 dst_release(dst);
764                 goto out;
765         }
766 
767         icmpv6_err_convert(type, code, &err);
768 
769         /* Might be for an open_request */
770         switch (sk->state) {
771                 struct open_request *req, **prev;
772                 struct ipv6hdr hd;
773         case TCP_LISTEN:
774                 if (sk->lock.users)
775                         goto out;
776 
777                 /* Grrrr - fix this later. */
778                 ipv6_addr_copy(&hd.saddr, saddr);
779                 ipv6_addr_copy(&hd.daddr, daddr); 
780                 req = tcp_v6_search_req(tp, &hd, th, tcp_v6_iif(skb), &prev);
781                 if (!req)
782                         goto out;
783 
784                 /* ICMPs are not backlogged, hence we cannot get
785                  * an established socket here.
786                  */
787                 BUG_TRAP(req->sk == NULL);
788 
789                 if (seq != req->snt_isn) {
790                         NET_INC_STATS_BH(OutOfWindowIcmps);
791                         goto out;
792                 }
793 
794                 tcp_synq_drop(sk, req, prev);
795                 goto out;
796 
797         case TCP_SYN_SENT:
798         case TCP_SYN_RECV:  /* Cannot happen.
799                                It can, it SYNs are crossed. --ANK */ 
800                 if (sk->lock.users == 0) {
801                         TCP_INC_STATS_BH(TcpAttemptFails);
802                         sk->err = err;
803                         sk->error_report(sk);           /* Wake people up to see the error (see connect in sock.c) */
804 
805                         tcp_done(sk);
806                 } else {
807                         sk->err_soft = err;
808                 }
809                 goto out;
810         }
811 
812         if (sk->lock.users == 0 && np->recverr) {
813                 sk->err = err;
814                 sk->error_report(sk);
815         } else {
816                 sk->err_soft = err;
817         }
818 
819 out:
820         bh_unlock_sock(sk);
821         sock_put(sk);
822 }
823 
824 
825 static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
826                               struct dst_entry *dst)
827 {
828         struct sk_buff * skb;
829         struct ipv6_txoptions *opt = NULL;
830         struct flowi fl;
831         int err = -1;
832 
833         fl.proto = IPPROTO_TCP;
834         fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
835         fl.nl_u.ip6_u.saddr = &req->af.v6_req.loc_addr;
836         fl.fl6_flowlabel = 0;
837         fl.oif = req->af.v6_req.iif;
838         fl.uli_u.ports.dport = req->rmt_port;
839         fl.uli_u.ports.sport = sk->sport;
840 
841         if (dst == NULL) {
842                 opt = sk->net_pinfo.af_inet6.opt;
843                 if (opt == NULL &&
844                     sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 &&
845                     req->af.v6_req.pktopts) {
846                         struct sk_buff *pktopts = req->af.v6_req.pktopts;
847                         struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
848                         if (rxopt->srcrt)
849                                 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
850                 }
851 
852                 if (opt && opt->srcrt) {
853                         struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
854                         fl.nl_u.ip6_u.daddr = rt0->addr;
855                 }
856 
857                 dst = ip6_route_output(sk, &fl);
858                 if (dst->error)
859                         goto done;
860         }
861 
862         skb = tcp_make_synack(sk, dst, req);
863         if (skb) {
864                 struct tcphdr *th = skb->h.th;
865 
866                 th->check = tcp_v6_check(th, skb->len,
867                                          &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr,
868                                          csum_partial((char *)th, skb->len, skb->csum));
869 
870                 fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
871                 err = ip6_xmit(sk, skb, &fl, opt);
872                 if (err == NET_XMIT_CN)
873                         err = 0;
874         }
875 
876 done:
877         dst_release(dst);
878         if (opt && opt != sk->net_pinfo.af_inet6.opt)
879                 sock_kfree_s(sk, opt, opt->tot_len);
880         return err;
881 }
882 
883 static void tcp_v6_or_free(struct open_request *req)
884 {
885         if (req->af.v6_req.pktopts)
886                 kfree_skb(req->af.v6_req.pktopts);
887 }
888 
889 static struct or_calltable or_ipv6 = {
890         AF_INET6,
891         tcp_v6_send_synack,
892         tcp_v6_or_send_ack,
893         tcp_v6_or_free,
894         tcp_v6_send_reset
895 };
896 
897 static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
898 {
899         struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
900 
901         if (sk->net_pinfo.af_inet6.rxopt.all) {
902                 if ((opt->hop && sk->net_pinfo.af_inet6.rxopt.bits.hopopts) ||
903                     ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
904                      sk->net_pinfo.af_inet6.rxopt.bits.rxflow) ||
905                     (opt->srcrt && sk->net_pinfo.af_inet6.rxopt.bits.srcrt) ||
906                     ((opt->dst1 || opt->dst0) && sk->net_pinfo.af_inet6.rxopt.bits.dstopts))
907                         return 1;
908         }
909         return 0;
910 }
911 
912 
913 static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
914                               struct sk_buff *skb)
915 {
916         struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
917         
918         th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 
919                                     csum_partial((char *)th, th->doff<<2, 
920                                                  skb->csum));
921 }
922 
923 
924 static void tcp_v6_send_reset(struct sk_buff *skb)
925 {
926         struct tcphdr *th = skb->h.th, *t1; 
927         struct sk_buff *buff;
928         struct flowi fl;
929 
930         if (th->rst)
931                 return;
932 
933         if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
934                 return; 
935 
936         /*
937          * We need to grab some memory, and put together an RST,
938          * and then put it into the queue to be sent.
939          */
940 
941         buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
942         if (buff == NULL) 
943                 return;
944 
945         skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
946 
947         t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr));
948 
949         /* Swap the send and the receive. */
950         memset(t1, 0, sizeof(*t1));
951         t1->dest = th->source;
952         t1->source = th->dest;
953         t1->doff = sizeof(*t1)/4;
954         t1->rst = 1;
955   
956         if(th->ack) {
957                 t1->seq = th->ack_seq;
958         } else {
959                 t1->ack = 1;
960                 t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
961                                     + skb->len - (th->doff<<2));
962         }
963 
964         buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
965 
966         fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
967         fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
968         fl.fl6_flowlabel = 0;
969 
970         t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
971                                     fl.nl_u.ip6_u.daddr, 
972                                     sizeof(*t1), IPPROTO_TCP,
973                                     buff->csum);
974 
975         fl.proto = IPPROTO_TCP;
976         fl.oif = tcp_v6_iif(skb);
977         fl.uli_u.ports.dport = t1->dest;
978         fl.uli_u.ports.sport = t1->source;
979 
980         /* sk = NULL, but it is safe for now. RST socket required. */
981         buff->dst = ip6_route_output(NULL, &fl);
982 
983         if (buff->dst->error == 0) {
984                 ip6_xmit(NULL, buff, &fl, NULL);
985                 TCP_INC_STATS_BH(TcpOutSegs);
986                 TCP_INC_STATS_BH(TcpOutRsts);
987                 return;
988         }
989 
990         kfree_skb(buff);
991 }
992 
993 static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
994 {
995         struct tcphdr *th = skb->h.th, *t1;
996         struct sk_buff *buff;
997         struct flowi fl;
998         int tot_len = sizeof(struct tcphdr);
999 
1000         buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
1001         if (buff == NULL)
1002                 return;
1003 
1004         skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
1005 
1006         if (ts)
1007                 tot_len += 3*4;
1008 
1009         t1 = (struct tcphdr *) skb_push(buff,tot_len);
1010 
1011         /* Swap the send and the receive. */
1012         memset(t1, 0, sizeof(*t1));
1013         t1->dest = th->source;
1014         t1->source = th->dest;
1015         t1->doff = tot_len/4;
1016         t1->seq = htonl(seq);
1017         t1->ack_seq = htonl(ack);
1018         t1->ack = 1;
1019         t1->window = htons(win);
1020         
1021         if (ts) {
1022                 u32 *ptr = (u32*)(t1 + 1);
1023                 *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
1024                                           (TCPOPT_NOP << 16) |
1025                                           (TCPOPT_TIMESTAMP << 8) |
1026                                           TCPOLEN_TIMESTAMP);
1027                 *ptr++ = htonl(tcp_time_stamp);
1028                 *ptr = htonl(ts);
1029         }
1030 
1031         buff->csum = csum_partial((char *)t1, tot_len, 0);
1032 
1033         fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
1034         fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
1035         fl.fl6_flowlabel = 0;
1036 
1037         t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
1038                                     fl.nl_u.ip6_u.daddr, 
1039                                     tot_len, IPPROTO_TCP,
1040                                     buff->csum);
1041 
1042         fl.proto = IPPROTO_TCP;
1043         fl.oif = tcp_v6_iif(skb);
1044         fl.uli_u.ports.dport = t1->dest;
1045         fl.uli_u.ports.sport = t1->source;
1046 
1047         buff->dst = ip6_route_output(NULL, &fl);
1048 
1049         if (buff->dst->error == 0) {
1050                 ip6_xmit(NULL, buff, &fl, NULL);
1051                 TCP_INC_STATS_BH(TcpOutSegs);
1052                 return;
1053         }
1054 
1055         kfree_skb(buff);
1056 }
1057 
1058 static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1059 {
1060         struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
1061 
1062         tcp_v6_send_ack(skb, tw->snd_nxt, tw->rcv_nxt,
1063                         tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent);
1064 
1065         tcp_tw_put(tw);
1066 }
1067 
1068 static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req)
1069 {
1070         tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent);
1071 }
1072 
1073 
1074 static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1075 {
1076         struct open_request *req, **prev;
1077         struct tcphdr *th = skb->h.th;
1078         struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
1079         struct sock *nsk;
1080 
1081         /* Find possible connection requests. */
1082         req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev);
1083         if (req)
1084                 return tcp_check_req(sk, skb, req, prev);
1085 
1086         nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr,
1087                                           th->source,
1088                                           &skb->nh.ipv6h->daddr,
1089                                           ntohs(th->dest),
1090                                           tcp_v6_iif(skb));
1091 
1092         if (nsk) {
1093                 if (nsk->state != TCP_TIME_WAIT) {
1094                         bh_lock_sock(nsk);
1095                         return nsk;
1096                 }
1097                 tcp_tw_put((struct tcp_tw_bucket*)sk);
1098                 return NULL;
1099         }
1100 
1101 #if 0 /*def CONFIG_SYN_COOKIES*/
1102         if (!th->rst && !th->syn && th->ack)
1103                 sk = cookie_v6_check(sk, skb, &(IPCB(skb)->opt));
1104 #endif
1105         return sk;
1106 }
1107 
1108 static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
1109 {
1110         struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
1111         struct tcp_listen_opt *lopt = tp->listen_opt;
1112         unsigned h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port);
1113 
1114         req->sk = NULL;
1115         req->expires = jiffies + TCP_TIMEOUT_INIT;
1116         req->retrans = 0;
1117         req->index = h;
1118         req->dl_next = lopt->syn_table[h];
1119 
1120         write_lock(&tp->syn_wait_lock);
1121         lopt->syn_table[h] = req;
1122         write_unlock(&tp->syn_wait_lock);
1123 
1124         tcp_synq_added(sk);
1125 }
1126 
1127 
1128 /* FIXME: this is substantially similar to the ipv4 code.
1129  * Can some kind of merge be done? -- erics
1130  */
1131 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1132 {
1133         struct tcp_opt tp;
1134         struct open_request *req = NULL;
1135         __u32 isn = TCP_SKB_CB(skb)->when;
1136 
1137         if (skb->protocol == __constant_htons(ETH_P_IP))
1138                 return tcp_v4_conn_request(sk, skb);
1139 
1140         /* FIXME: do the same check for anycast */
1141         if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
1142                 goto drop; 
1143 
1144         /*
1145          *      There are no SYN attacks on IPv6, yet...        
1146          */
1147         if (tcp_synq_is_full(sk) && !isn) {
1148                 if (net_ratelimit())
1149                         printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n");
1150                 goto drop;              
1151         }
1152 
1153         if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
1154                 goto drop;
1155 
1156         req = tcp_openreq_alloc();
1157         if (req == NULL)
1158                 goto drop;
1159 
1160         tcp_clear_options(&tp);
1161         tp.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
1162         tp.user_mss = sk->tp_pinfo.af_tcp.user_mss;
1163 
1164         tcp_parse_options(skb, &tp, 0);
1165 
1166         tcp_openreq_init(req, &tp, skb);
1167 
1168         req->class = &or_ipv6;
1169         ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr);
1170         ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr);
1171         TCP_ECN_create_request(req, skb->h.th);
1172         req->af.v6_req.pktopts = NULL;
1173         if (ipv6_opt_accepted(sk, skb) ||
1174             sk->net_pinfo.af_inet6.rxopt.bits.rxinfo ||
1175             sk->net_pinfo.af_inet6.rxopt.bits.rxhlim) {
1176                 atomic_inc(&skb->users);
1177                 req->af.v6_req.pktopts = skb;
1178         }
1179         req->af.v6_req.iif = sk->bound_dev_if;
1180 
1181         /* So that link locals have meaning */
1182         if (!sk->bound_dev_if && ipv6_addr_type(&req->af.v6_req.rmt_addr)&IPV6_ADDR_LINKLOCAL)
1183                 req->af.v6_req.iif = tcp_v6_iif(skb);
1184 
1185         if (isn == 0) 
1186                 isn = tcp_v6_init_sequence(sk,skb);
1187 
1188         req->snt_isn = isn;
1189 
1190         if (tcp_v6_send_synack(sk, req, NULL))
1191                 goto drop;
1192 
1193         tcp_v6_synq_add(sk, req);
1194 
1195         return 0;
1196 
1197 drop:
1198         if (req)
1199                 tcp_openreq_free(req);
1200 
1201         TCP_INC_STATS_BH(TcpAttemptFails);
1202         return 0; /* don't send reset */
1203 }
1204 
1205 static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1206                                           struct open_request *req,
1207                                           struct dst_entry *dst)
1208 {
1209         struct ipv6_pinfo *np;
1210         struct flowi fl;
1211         struct tcp_opt *newtp;
1212         struct sock *newsk;
1213         struct ipv6_txoptions *opt;
1214 
1215         if (skb->protocol == __constant_htons(ETH_P_IP)) {
1216                 /*
1217                  *      v6 mapped
1218                  */
1219 
1220                 newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst);
1221 
1222                 if (newsk == NULL) 
1223                         return NULL;
1224 
1225                 np = &newsk->net_pinfo.af_inet6;
1226 
1227                 ipv6_addr_set(&np->daddr, 0, 0, __constant_htonl(0x0000FFFF),
1228                               newsk->daddr);
1229 
1230                 ipv6_addr_set(&np->saddr, 0, 0, __constant_htonl(0x0000FFFF),
1231                               newsk->saddr);
1232 
1233                 ipv6_addr_copy(&np->rcv_saddr, &np->saddr);
1234 
1235                 newsk->tp_pinfo.af_tcp.af_specific = &ipv6_mapped;
1236                 newsk->backlog_rcv = tcp_v4_do_rcv;
1237                 newsk->net_pinfo.af_inet6.pktoptions = NULL;
1238                 newsk->net_pinfo.af_inet6.opt = NULL;
1239                 newsk->net_pinfo.af_inet6.mcast_oif = tcp_v6_iif(skb);
1240                 newsk->net_pinfo.af_inet6.mcast_hops = skb->nh.ipv6h->hop_limit;
1241 
1242                 /* Charge newly allocated IPv6 socket. Though it is mapped,
1243                  * it is IPv6 yet.
1244                  */
1245 #ifdef INET_REFCNT_DEBUG
1246                 atomic_inc(&inet6_sock_nr);
1247 #endif
1248                 MOD_INC_USE_COUNT;
1249 
1250                 /* It is tricky place. Until this moment IPv4 tcp
1251                    worked with IPv6 af_tcp.af_specific.
1252                    Sync it now.
1253                  */
1254                 tcp_sync_mss(newsk, newsk->tp_pinfo.af_tcp.pmtu_cookie);
1255 
1256                 return newsk;
1257         }
1258 
1259         opt = sk->net_pinfo.af_inet6.opt;
1260 
1261         if (tcp_acceptq_is_full(sk))
1262                 goto out_overflow;
1263 
1264         if (sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 &&
1265             opt == NULL && req->af.v6_req.pktopts) {
1266                 struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb;
1267                 if (rxopt->srcrt)
1268                         opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
1269         }
1270 
1271         if (dst == NULL) {
1272                 fl.proto = IPPROTO_TCP;
1273                 fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
1274                 if (opt && opt->srcrt) {
1275                         struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
1276                         fl.nl_u.ip6_u.daddr = rt0->addr;
1277                 }
1278                 fl.nl_u.ip6_u.saddr = &req->af.v6_req.loc_addr;
1279                 fl.fl6_flowlabel = 0;
1280                 fl.oif = sk->bound_dev_if;
1281                 fl.uli_u.ports.dport = req->rmt_port;
1282                 fl.uli_u.ports.sport = sk->sport;
1283 
1284                 dst = ip6_route_output(sk, &fl);
1285         }
1286 
1287         if (dst->error)
1288                 goto out;
1289 
1290         newsk = tcp_create_openreq_child(sk, req, skb);
1291         if (newsk == NULL)
1292                 goto out;
1293 
1294         /* Charge newly allocated IPv6 socket */
1295 #ifdef INET_REFCNT_DEBUG
1296         atomic_inc(&inet6_sock_nr);
1297 #endif
1298         MOD_INC_USE_COUNT;
1299 
1300         ip6_dst_store(newsk, dst, NULL);
1301 
1302         newtp = &(newsk->tp_pinfo.af_tcp);
1303 
1304         np = &newsk->net_pinfo.af_inet6;
1305         ipv6_addr_copy(&np->daddr, &req->af.v6_req.rmt_addr);
1306         ipv6_addr_copy(&np->saddr, &req->af.v6_req.loc_addr);
1307         ipv6_addr_copy(&np->rcv_saddr, &req->af.v6_req.loc_addr);
1308         newsk->bound_dev_if = req->af.v6_req.iif;
1309 
1310         /* Now IPv6 options... 
1311 
1312            First: no IPv4 options.
1313          */
1314         newsk->protinfo.af_inet.opt = NULL;
1315 
1316         /* Clone RX bits */
1317         np->rxopt.all = sk->net_pinfo.af_inet6.rxopt.all;
1318 
1319         /* Clone pktoptions received with SYN */
1320         np->pktoptions = NULL;
1321         if (req->af.v6_req.pktopts) {
1322                 np->pktoptions = skb_clone(req->af.v6_req.pktopts, GFP_ATOMIC);
1323                 kfree_skb(req->af.v6_req.pktopts);
1324                 req->af.v6_req.pktopts = NULL;
1325                 if (np->pktoptions)
1326                         skb_set_owner_r(np->pktoptions, newsk);
1327         }
1328         np->opt = NULL;
1329         np->mcast_oif = tcp_v6_iif(skb);
1330         np->mcast_hops = skb->nh.ipv6h->hop_limit;
1331 
1332         /* Clone native IPv6 options from listening socket (if any)
1333 
1334            Yes, keeping reference count would be much more clever,
1335            but we make one more one thing there: reattach optmem
1336            to newsk.
1337          */
1338         if (opt) {
1339                 np->opt = ipv6_dup_options(newsk, opt);
1340                 if (opt != sk->net_pinfo.af_inet6.opt)
1341                         sock_kfree_s(sk, opt, opt->tot_len);
1342         }
1343 
1344         newtp->ext_header_len = 0;
1345         if (np->opt)
1346                 newtp->ext_header_len = np->opt->opt_nflen + np->opt->opt_flen;
1347 
1348         tcp_sync_mss(newsk, dst->pmtu);
1349         newtp->advmss = dst->advmss;
1350         tcp_initialize_rcv_mss(newsk);
1351 
1352         newsk->daddr    = LOOPBACK4_IPV6;
1353         newsk->saddr    = LOOPBACK4_IPV6;
1354         newsk->rcv_saddr= LOOPBACK4_IPV6;
1355 
1356         __tcp_v6_hash(newsk);
1357         tcp_inherit_port(sk, newsk);
1358 
1359         return newsk;
1360 
1361 out_overflow:
1362         NET_INC_STATS_BH(ListenOverflows);
1363 out:
1364         NET_INC_STATS_BH(ListenDrops);
1365         if (opt && opt != sk->net_pinfo.af_inet6.opt)
1366                 sock_kfree_s(sk, opt, opt->tot_len);
1367         dst_release(dst);
1368         return NULL;
1369 }
1370 
1371 static int tcp_v6_checksum_init(struct sk_buff *skb)
1372 {
1373         if (skb->ip_summed == CHECKSUM_HW) {
1374                 if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1375                                  &skb->nh.ipv6h->daddr,skb->csum)) {
1376                         NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
1377                         return -1;
1378                 }
1379                 skb->ip_summed = CHECKSUM_UNNECESSARY;
1380         } else {
1381                 if (skb->len <= 76) {
1382                         if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1383                                          &skb->nh.ipv6h->daddr,csum_partial((char *)skb->h.th, skb->len, 0)))
1384                                 return -1;
1385                         skb->ip_summed = CHECKSUM_UNNECESSARY;
1386                 } else {
1387                         skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1388                                                   &skb->nh.ipv6h->daddr,0);
1389                 }
1390         }
1391         return 0;
1392 }
1393 
1394 /* The socket must have it's spinlock held when we get
1395  * here.
1396  *
1397  * We have a potential double-lock case here, so even when
1398  * doing backlog processing we use the BH locking scheme.
1399  * This is because we cannot sleep with the original spinlock
1400  * held.
1401  */
1402 static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1403 {
1404 #ifdef CONFIG_FILTER
1405         struct sk_filter *filter;
1406 #endif
1407         struct sk_buff *opt_skb = NULL;
1408 
1409         /* Imagine: socket is IPv6. IPv4 packet arrives,
1410            goes to IPv4 receive handler and backlogged.
1411            From backlog it always goes here. Kerboom...
1412            Fortunately, tcp_rcv_established and rcv_established
1413            handle them correctly, but it is not case with
1414            tcp_v6_hnd_req and tcp_v6_send_reset().   --ANK
1415          */
1416 
1417         if (skb->protocol == __constant_htons(ETH_P_IP))
1418                 return tcp_v4_do_rcv(sk, skb);
1419 
1420 #ifdef CONFIG_FILTER
1421         filter = sk->filter;
1422         if (filter && sk_filter(skb, filter))
1423                 goto discard;
1424 #endif /* CONFIG_FILTER */
1425 
1426         /*
1427          *      socket locking is here for SMP purposes as backlog rcv
1428          *      is currently called with bh processing disabled.
1429          */
1430 
1431         IP6_INC_STATS_BH(Ip6InDelivers);
1432 
1433         /* Do Stevens' IPV6_PKTOPTIONS.
1434 
1435            Yes, guys, it is the only place in our code, where we
1436            may make it not affecting IPv4.
1437            The rest of code is protocol independent,
1438            and I do not like idea to uglify IPv4.
1439 
1440            Actually, all the idea behind IPV6_PKTOPTIONS
1441            looks not very well thought. For now we latch
1442            options, received in the last packet, enqueued
1443            by tcp. Feel free to propose better solution.
1444                                                --ANK (980728)
1445          */
1446         if (sk->net_pinfo.af_inet6.rxopt.all)
1447                 opt_skb = skb_clone(skb, GFP_ATOMIC);
1448 
1449         if (sk->state == TCP_ESTABLISHED) { /* Fast path */
1450                 TCP_CHECK_TIMER(sk);
1451                 if (tcp_rcv_established(sk, skb, skb->h.th, skb->len))
1452                         goto reset;
1453                 TCP_CHECK_TIMER(sk);
1454                 if (opt_skb)
1455                         goto ipv6_pktoptions;
1456                 return 0;
1457         }
1458 
1459         if (skb->len < (skb->h.th->doff<<2) || tcp_checksum_complete(skb))
1460                 goto csum_err;
1461 
1462         if (sk->state == TCP_LISTEN) { 
1463                 struct sock *nsk = tcp_v6_hnd_req(sk, skb);
1464                 if (!nsk)
1465                         goto discard;
1466 
1467                 /*
1468                  * Queue it on the new socket if the new socket is active,
1469                  * otherwise we just shortcircuit this and continue with
1470                  * the new socket..
1471                  */
1472                 if(nsk != sk) {
1473                         if (tcp_child_process(sk, nsk, skb))
1474                                 goto reset;
1475                         if (opt_skb)
1476                                 __kfree_skb(opt_skb);
1477                         return 0;
1478                 }
1479         }
1480 
1481         TCP_CHECK_TIMER(sk);
1482         if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len))
1483                 goto reset;
1484         TCP_CHECK_TIMER(sk);
1485         if (opt_skb)
1486                 goto ipv6_pktoptions;
1487         return 0;
1488 
1489 reset:
1490         tcp_v6_send_reset(skb);
1491 discard:
1492         if (opt_skb)
1493                 __kfree_skb(opt_skb);
1494         kfree_skb(skb);
1495         return 0;
1496 csum_err:
1497         TCP_INC_STATS_BH(TcpInErrs);
1498         goto discard;
1499 
1500 
1501 ipv6_pktoptions:
1502         /* Do you ask, what is it?
1503 
1504            1. skb was enqueued by tcp.
1505            2. skb is added to tail of read queue, rather than out of order.
1506            3. socket is not in passive state.
1507            4. Finally, it really contains options, which user wants to receive.
1508          */
1509         if (TCP_SKB_CB(opt_skb)->end_seq == sk->tp_pinfo.af_tcp.rcv_nxt &&
1510             !((1<<sk->state)&(TCPF_CLOSE|TCPF_LISTEN))) {
1511                 if (sk->net_pinfo.af_inet6.rxopt.bits.rxinfo)
1512                         sk->net_pinfo.af_inet6.mcast_oif = tcp_v6_iif(opt_skb);
1513                 if (sk->net_pinfo.af_inet6.rxopt.bits.rxhlim)
1514                         sk->net_pinfo.af_inet6.mcast_hops = opt_skb->nh.ipv6h->hop_limit;
1515                 if (ipv6_opt_accepted(sk, opt_skb)) {
1516                         skb_set_owner_r(opt_skb, sk);
1517                         opt_skb = xchg(&sk->net_pinfo.af_inet6.pktoptions, opt_skb);
1518                 } else {
1519                         __kfree_skb(opt_skb);
1520                         opt_skb = xchg(&sk->net_pinfo.af_inet6.pktoptions, NULL);
1521                 }
1522         }
1523 
1524         if (opt_skb)
1525                 kfree_skb(opt_skb);
1526         return 0;
1527 }
1528 
1529 int tcp_v6_rcv(struct sk_buff *skb, unsigned long len)
1530 {
1531         struct tcphdr *th;      
1532         struct sock *sk;
1533         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
1534         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
1535         int ret;
1536 
1537         th = skb->h.th;
1538 
1539         if (skb->pkt_type != PACKET_HOST)
1540                 goto discard_it;
1541 
1542         /*
1543          *      Pull up the IP header.
1544          */
1545 
1546         __skb_pull(skb, skb->h.raw - skb->data);
1547 
1548         /*
1549          *      Count it even if it's bad.
1550          */
1551 
1552         TCP_INC_STATS_BH(TcpInSegs);
1553 
1554         if (th->doff < sizeof(struct tcphdr)/4 ||
1555             (skb->ip_summed != CHECKSUM_UNNECESSARY &&
1556              tcp_v6_checksum_init(skb) < 0))
1557                 goto bad_packet;
1558 
1559         TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1560         TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1561                                     len - th->doff*4);
1562         TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1563         TCP_SKB_CB(skb)->when = 0;
1564         TCP_SKB_CB(skb)->flags = ip6_get_dsfield(skb->nh.ipv6h);
1565         TCP_SKB_CB(skb)->sacked = 0;
1566         skb->used = 0;
1567 
1568         sk = __tcp_v6_lookup(saddr, th->source, daddr, ntohs(th->dest), tcp_v6_iif(skb));
1569 
1570         if (!sk)
1571                 goto no_tcp_socket;
1572 
1573 process:
1574         if(!ipsec_sk_policy(sk,skb))
1575                 goto discard_and_relse;
1576         if(sk->state == TCP_TIME_WAIT)
1577                 goto do_time_wait;
1578 
1579         skb->dev = NULL;
1580 
1581         bh_lock_sock(sk);
1582         ret = 0;
1583         if (!sk->lock.users) {
1584                 if (!tcp_prequeue(sk, skb))
1585                         ret = tcp_v6_do_rcv(sk, skb);
1586         } else
1587                 sk_add_backlog(sk, skb);
1588         bh_unlock_sock(sk);
1589 
1590         sock_put(sk);
1591         return ret;
1592 
1593 no_tcp_socket:
1594         if (len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1595 bad_packet:
1596                 TCP_INC_STATS_BH(TcpInErrs);
1597         } else {
1598                 tcp_v6_send_reset(skb);
1599         }
1600 
1601 discard_it:
1602 
1603         /*
1604          *      Discard frame
1605          */
1606 
1607         kfree_skb(skb);
1608         return 0;
1609 
1610 discard_and_relse:
1611         sock_put(sk);
1612         goto discard_it;
1613 
1614 do_time_wait:
1615         if (len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1616                 TCP_INC_STATS_BH(TcpInErrs);
1617                 sock_put(sk);
1618                 goto discard_it;
1619         }
1620 
1621         switch(tcp_timewait_state_process((struct tcp_tw_bucket *)sk,
1622                                           skb, th, skb->len)) {
1623         case TCP_TW_SYN:
1624         {
1625                 struct sock *sk2;
1626 
1627                 sk2 = tcp_v6_lookup_listener(&skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb));
1628                 if (sk2 != NULL) {
1629                         tcp_tw_deschedule((struct tcp_tw_bucket *)sk);
1630                         tcp_timewait_kill((struct tcp_tw_bucket *)sk);
1631                         tcp_tw_put((struct tcp_tw_bucket *)sk);
1632                         sk = sk2;
1633                         goto process;
1634                 }
1635                 /* Fall through to ACK */
1636         }
1637         case TCP_TW_ACK:
1638                 tcp_v6_timewait_ack(sk, skb);
1639                 break;
1640         case TCP_TW_RST:
1641                 goto no_tcp_socket;
1642         case TCP_TW_SUCCESS:;
1643         }
1644         goto discard_it;
1645 }
1646 
1647 static int tcp_v6_rebuild_header(struct sock *sk)
1648 {
1649         int err;
1650         struct dst_entry *dst;
1651         struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
1652 
1653         dst = __sk_dst_check(sk, np->dst_cookie);
1654 
1655         if (dst == NULL) {
1656                 struct flowi fl;
1657 
1658                 fl.proto = IPPROTO_TCP;
1659                 fl.nl_u.ip6_u.daddr = &np->daddr;
1660                 fl.nl_u.ip6_u.saddr = &np->saddr;
1661                 fl.fl6_flowlabel = np->flow_label;
1662                 fl.oif = sk->bound_dev_if;
1663                 fl.uli_u.ports.dport = sk->dport;
1664                 fl.uli_u.ports.sport = sk->sport;
1665 
1666                 if (np->opt && np->opt->srcrt) {
1667                         struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
1668                         fl.nl_u.ip6_u.daddr = rt0->addr;
1669                 }
1670 
1671                 dst = ip6_route_output(sk, &fl);
1672 
1673                 if (dst->error) {
1674                         err = dst->error;
1675                         dst_release(dst);
1676                         return err;
1677                 }
1678 
1679                 ip6_dst_store(sk, dst, NULL);
1680         }
1681 
1682         return 0;
1683 }
1684 
1685 static int tcp_v6_xmit(struct sk_buff *skb)
1686 {
1687         struct sock *sk = skb->sk;
1688         struct ipv6_pinfo * np = &sk->net_pinfo.af_inet6;
1689         struct flowi fl;
1690         struct dst_entry *dst;
1691 
1692         fl.proto = IPPROTO_TCP;
1693         fl.fl6_dst = &np->daddr;
1694         fl.fl6_src = &np->saddr;
1695         fl.fl6_flowlabel = np->flow_label;
1696         IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
1697         fl.oif = sk->bound_dev_if;
1698         fl.uli_u.ports.sport = sk->sport;
1699         fl.uli_u.ports.dport = sk->dport;
1700 
1701         if (np->opt && np->opt->srcrt) {
1702                 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
1703                 fl.nl_u.ip6_u.daddr = rt0->addr;
1704         }
1705 
1706         dst = __sk_dst_check(sk, np->dst_cookie);
1707 
1708         if (dst == NULL) {
1709                 dst = ip6_route_output(sk, &fl);
1710 
1711                 if (dst->error) {
1712                         sk->err_soft = -dst->error;
1713                         dst_release(dst);
1714                         return -sk->err_soft;
1715                 }
1716 
1717                 ip6_dst_store(sk, dst, NULL);
1718         }
1719 
1720         skb->dst = dst_clone(dst);
1721 
1722         /* Restore final destination back after routing done */
1723         fl.nl_u.ip6_u.daddr = &np->daddr;
1724 
1725         return ip6_xmit(sk, skb, &fl, np->opt);
1726 }
1727 
1728 static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
1729 {
1730         struct ipv6_pinfo * np = &sk->net_pinfo.af_inet6;
1731         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
1732 
1733         sin6->sin6_family = AF_INET6;
1734         memcpy(&sin6->sin6_addr, &np->daddr, sizeof(struct in6_addr));
1735         sin6->sin6_port = sk->dport;
1736         /* We do not store received flowlabel for TCP */
1737         sin6->sin6_flowinfo = 0;
1738         sin6->sin6_scope_id = 0;
1739         if (sk->bound_dev_if && ipv6_addr_type(&sin6->sin6_addr)&IPV6_ADDR_LINKLOCAL)
1740                 sin6->sin6_scope_id = sk->bound_dev_if;
1741 }
1742 
1743 static int tcp_v6_remember_stamp(struct sock *sk)
1744 {
1745         /* Alas, not yet... */
1746         return 0;
1747 }
1748 
1749 static struct tcp_func ipv6_specific = {
1750         tcp_v6_xmit,
1751         tcp_v6_send_check,
1752         tcp_v6_rebuild_header,
1753         tcp_v6_conn_request,
1754         tcp_v6_syn_recv_sock,
1755         tcp_v6_hash_connecting,
1756         tcp_v6_remember_stamp,
1757         sizeof(struct ipv6hdr),
1758 
1759         ipv6_setsockopt,
1760         ipv6_getsockopt,
1761         v6_addr2sockaddr,
1762         sizeof(struct sockaddr_in6)
1763 };
1764 
1765 /*
1766  *      TCP over IPv4 via INET6 API
1767  */
1768 
1769 static struct tcp_func ipv6_mapped = {
1770         ip_queue_xmit,
1771         tcp_v4_send_check,
1772         tcp_v4_rebuild_header,
1773         tcp_v6_conn_request,
1774         tcp_v6_syn_recv_sock,
1775         tcp_v4_hash_connecting,
1776         tcp_v4_remember_stamp,
1777         sizeof(struct iphdr),
1778 
1779         ipv6_setsockopt,
1780         ipv6_getsockopt,
1781         v6_addr2sockaddr,
1782         sizeof(struct sockaddr_in6)
1783 };
1784 
1785 
1786 
1787 /* NOTE: A lot of things set to zero explicitly by call to
1788  *       sk_alloc() so need not be done here.
1789  */
1790 static int tcp_v6_init_sock(struct sock *sk)
1791 {
1792         struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
1793 
1794         skb_queue_head_init(&tp->out_of_order_queue);
1795         tcp_init_xmit_timers(sk);
1796         tcp_prequeue_init(tp);
1797 
1798         tp->rto  = TCP_TIMEOUT_INIT;
1799         tp->mdev = TCP_TIMEOUT_INIT;
1800 
1801         /* So many TCP implementations out there (incorrectly) count the
1802          * initial SYN frame in their delayed-ACK and congestion control
1803          * algorithms that we must have the following bandaid to talk
1804          * efficiently to them.  -DaveM
1805          */
1806         tp->snd_cwnd = 2;
1807 
1808         /* See draft-stevens-tcpca-spec-01 for discussion of the
1809          * initialization of these values.
1810          */
1811         tp->snd_ssthresh = 0x7fffffff;
1812         tp->snd_cwnd_clamp = ~0;
1813         tp->mss_cache = 536;
1814 
1815         tp->reordering = sysctl_tcp_reordering;
1816 
1817         sk->state = TCP_CLOSE;
1818 
1819         sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific;
1820 
1821         sk->write_space = tcp_write_space;
1822 
1823         sk->sndbuf = sysctl_tcp_wmem[1];
1824         sk->rcvbuf = sysctl_tcp_rmem[1];
1825 
1826         atomic_inc(&tcp_sockets_allocated);
1827 
1828         return 0;
1829 }
1830 
1831 static int tcp_v6_destroy_sock(struct sock *sk)
1832 {
1833         struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
1834 
1835         tcp_clear_xmit_timers(sk);
1836 
1837         /* Cleanup up the write buffer. */
1838         tcp_writequeue_purge(sk);
1839 
1840         /* Cleans up our, hopefuly empty, out_of_order_queue. */
1841         __skb_queue_purge(&tp->out_of_order_queue);
1842 
1843         /* Clean prequeue, it must be empty really */
1844         __skb_queue_purge(&tp->ucopy.prequeue);
1845 
1846         /* Clean up a referenced TCP bind bucket. */
1847         if(sk->prev != NULL)
1848                 tcp_put_port(sk);
1849 
1850         atomic_dec(&tcp_sockets_allocated);
1851 
1852         return inet6_destroy_sock(sk);
1853 }
1854 
1855 /* Proc filesystem TCPv6 sock list dumping. */
1856 static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf, int i, int uid)
1857 {
1858         struct in6_addr *dest, *src;
1859         int ttd = req->expires - jiffies;
1860 
1861         if (ttd < 0)
1862                 ttd = 0;
1863 
1864         src = &req->af.v6_req.loc_addr;
1865         dest = &req->af.v6_req.rmt_addr;
1866         sprintf(tmpbuf,
1867                 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1868                 "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
1869                 i,
1870                 src->s6_addr32[0], src->s6_addr32[1],
1871                 src->s6_addr32[2], src->s6_addr32[3],
1872                 ntohs(sk->sport),
1873                 dest->s6_addr32[0], dest->s6_addr32[1],
1874                 dest->s6_addr32[2], dest->s6_addr32[3],
1875                 ntohs(req->rmt_port),
1876                 TCP_SYN_RECV,
1877                 0,0, /* could print option size, but that is af dependent. */
1878                 1,   /* timers active (only the expire timer) */  
1879                 ttd, 
1880                 req->retrans,
1881                 uid,
1882                 0,  /* non standard timer */  
1883                 0, /* open_requests have no inode */
1884                 0, req);
1885 }
1886 
1887 static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i)
1888 {
1889         struct in6_addr *dest, *src;
1890         __u16 destp, srcp;
1891         int timer_active;
1892         unsigned long timer_expires;
1893         struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
1894 
1895         dest  = &sp->net_pinfo.af_inet6.daddr;
1896         src   = &sp->net_pinfo.af_inet6.rcv_saddr;
1897         destp = ntohs(sp->dport);
1898         srcp  = ntohs(sp->sport);
1899         if (tp->pending == TCP_TIME_RETRANS) {
1900                 timer_active    = 1;
1901                 timer_expires   = tp->timeout;
1902         } else if (tp->pending == TCP_TIME_PROBE0) {
1903                 timer_active    = 4;
1904                 timer_expires   = tp->timeout;
1905         } else if (timer_pending(&sp->timer)) {
1906                 timer_active    = 2;
1907                 timer_expires   = sp->timer.expires;
1908         } else {
1909                 timer_active    = 0;
1910                 timer_expires = jiffies;
1911         }
1912 
1913         sprintf(tmpbuf,
1914                 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1915                 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d",
1916                 i,
1917                 src->s6_addr32[0], src->s6_addr32[1],
1918                 src->s6_addr32[2], src->s6_addr32[3], srcp,
1919                 dest->s6_addr32[0], dest->s6_addr32[1],
1920                 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1921                 sp->state, 
1922                 tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
1923                 timer_active, timer_expires-jiffies,
1924                 tp->retransmits,
1925                 sock_i_uid(sp),
1926                 tp->probes_out,
1927                 sock_i_ino(sp),
1928                 atomic_read(&sp->refcnt), sp,
1929                 tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong,
1930                 tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
1931                 );
1932 }
1933 
1934 static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i)
1935 {
1936         struct in6_addr *dest, *src;
1937         __u16 destp, srcp;
1938         int ttd = tw->ttd - jiffies;
1939 
1940         if (ttd < 0)
1941                 ttd = 0;
1942 
1943         dest  = &tw->v6_daddr;
1944         src   = &tw->v6_rcv_saddr;
1945         destp = ntohs(tw->dport);
1946         srcp  = ntohs(tw->sport);
1947 
1948         sprintf(tmpbuf,
1949                 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1950                 "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
1951                 i,
1952                 src->s6_addr32[0], src->s6_addr32[1],
1953                 src->s6_addr32[2], src->s6_addr32[3], srcp,
1954                 dest->s6_addr32[0], dest->s6_addr32[1],
1955                 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1956                 tw->substate, 0, 0,
1957                 3, ttd, 0, 0, 0, 0,
1958                 atomic_read(&tw->refcnt), tw);
1959 }
1960 
1961 #define LINE_LEN 190
1962 #define LINE_FMT "%-190s\n"
1963 
1964 int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
1965 {
1966         int len = 0, num = 0, i;
1967         off_t begin, pos = 0;
1968         char tmpbuf[LINE_LEN+2];
1969 
1970         if(offset < LINE_LEN+1)
1971                 len += sprintf(buffer, LINE_FMT,
1972                                "  sl  "                                         /* 6 */
1973                                "local_address                         "         /* 38 */
1974                                "remote_address                        "         /* 38 */
1975                                "st tx_queue rx_queue tr tm->when retrnsmt"      /* 41 */
1976                                "   uid  timeout inode");                        /* 21 */
1977                                                                                 /*----*/
1978                                                                                 /*144 */
1979 
1980         pos = LINE_LEN+1;
1981 
1982         /* First, walk listening socket table. */
1983         tcp_listen_lock();
1984         for(i = 0; i < TCP_LHTABLE_SIZE; i++) {
1985                 struct sock *sk = tcp_listening_hash[i];
1986                 struct tcp_listen_opt *lopt;
1987                 int k;
1988 
1989                 for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) {
1990                         struct open_request *req;
1991                         int uid;
1992                         struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
1993 
1994                         if (sk->family != PF_INET6)
1995                                 continue;
1996                         pos += LINE_LEN+1;
1997                         if (pos >= offset) {
1998                                 get_tcp6_sock(sk, tmpbuf, num);
1999                                 len += sprintf(buffer+len, LINE_FMT, tmpbuf);
2000                                 if (len >= length) {
2001                                         tcp_listen_unlock();
2002                                         goto out_no_bh;
2003                                 }
2004                         }
2005 
2006                         uid = sock_i_uid(sk);
2007                         read_lock_bh(&tp->syn_wait_lock);
2008                         lopt = tp->listen_opt;
2009                         if (lopt && lopt->qlen != 0) {
2010                                 for (k=0; k<TCP_SYNQ_HSIZE; k++) {
2011                                         for (req = lopt->syn_table[k]; req; req = req->dl_next, num++) {
2012                                                 if (req->class->family != PF_INET6)
2013                                                         continue;
2014                                                 pos += LINE_LEN+1;
2015                                                 if (pos <= offset)
2016                                                         continue;
2017                                                 get_openreq6(sk, req, tmpbuf, num, uid);
2018                                                 len += sprintf(buffer+len, LINE_FMT, tmpbuf);
2019                                                 if(len >= length) { 
2020                                                         read_unlock_bh(&tp->syn_wait_lock);
2021                                                         tcp_listen_unlock();
2022                                                         goto out_no_bh;
2023                                                 }
2024                                         }
2025                                 }
2026                         }
2027                         read_unlock_bh(&tp->syn_wait_lock);
2028 
2029                         /* Completed requests are in normal socket hash table */
2030                 }
2031         }
2032         tcp_listen_unlock();
2033 
2034         local_bh_disable();
2035 
2036         /* Next, walk established hash chain. */
2037         for (i = 0; i < tcp_ehash_size; i++) {
2038                 struct tcp_ehash_bucket *head = &tcp_ehash[i];
2039                 struct sock *sk;
2040                 struct tcp_tw_bucket *tw;
2041 
2042                 read_lock(&head->lock);
2043                 for(sk = head->chain; sk; sk = sk->next, num++) {
2044                         if (sk->family != PF_INET6)
2045                                 continue;
2046                         pos += LINE_LEN+1;
2047                         if (pos <= offset)
2048                                 continue;
2049                         get_tcp6_sock(sk, tmpbuf, num);
2050                         len += sprintf(buffer+len, LINE_FMT, tmpbuf);
2051                         if(len >= length) {
2052                                 read_unlock(&head->lock);
2053                                 goto out;
2054                         }
2055                 }
2056                 for (tw = (struct tcp_tw_bucket *)tcp_ehash[i+tcp_ehash_size].chain;
2057                      tw != NULL;
2058                      tw = (struct tcp_tw_bucket *)tw->next, num++) {
2059                         if (tw->family != PF_INET6)
2060                                 continue;
2061                         pos += LINE_LEN+1;
2062                         if (pos <= offset)
2063                                 continue;
2064                         get_timewait6_sock(tw, tmpbuf, num);
2065                         len += sprintf(buffer+len, LINE_FMT, tmpbuf);
2066                         if(len >= length) {
2067                                 read_unlock(&head->lock);
2068                                 goto out;
2069                         }
2070                 }
2071                 read_unlock(&head->lock);
2072         }
2073 
2074 out:
2075         local_bh_enable();
2076 out_no_bh:
2077 
2078         begin = len - (pos - offset);
2079         *start = buffer + begin;
2080         len -= begin;
2081         if(len > length)
2082                 len = length;
2083         if (len < 0)
2084                 len = 0; 
2085         return len;
2086 }
2087 
2088 struct proto tcpv6_prot = {
2089         name:           "TCPv6",
2090         close:          tcp_close,
2091         connect:        tcp_v6_connect,
2092         disconnect:     tcp_disconnect,
2093         accept:         tcp_accept,
2094         ioctl:          tcp_ioctl,
2095         init:           tcp_v6_init_sock,
2096         destroy:        tcp_v6_destroy_sock,
2097         shutdown:       tcp_shutdown,
2098         setsockopt:     tcp_setsockopt,
2099         getsockopt:     tcp_getsockopt,
2100         sendmsg:        tcp_sendmsg,
2101         recvmsg:        tcp_recvmsg,
2102         backlog_rcv:    tcp_v6_do_rcv,
2103         hash:           tcp_v6_hash,
2104         unhash:         tcp_unhash,
2105         get_port:       tcp_v6_get_port,
2106 };
2107 
2108 static struct inet6_protocol tcpv6_protocol =
2109 {
2110         tcp_v6_rcv,             /* TCP handler          */
2111         tcp_v6_err,             /* TCP error control    */
2112         NULL,                   /* next                 */
2113         IPPROTO_TCP,            /* protocol ID          */
2114         0,                      /* copy                 */
2115         NULL,                   /* data                 */
2116         "TCPv6"                 /* name                 */
2117 };
2118 
2119 void __init tcpv6_init(void)
2120 {
2121         /* register inet6 protocol */
2122         inet6_add_protocol(&tcpv6_protocol);
2123 }
2124 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.