ipv6: no more dev_put() in datagram_send_ctl()
[safe/jmp/linux-2.6] / net / ipv6 / tcp_ipv6.c
index eadbc58..34925f0 100644 (file)
@@ -75,8 +75,8 @@ static void   tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 
 static int     tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
 
-static struct inet_connection_sock_af_ops ipv6_mapped;
-static struct inet_connection_sock_af_ops ipv6_specific;
+static const struct inet_connection_sock_af_ops ipv6_mapped;
+static const struct inet_connection_sock_af_ops ipv6_specific;
 #ifdef CONFIG_TCP_MD5SIG
 static const struct tcp_sock_af_ops tcp_sock_ipv6_specific;
 static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
@@ -226,10 +226,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 #endif
                        goto failure;
                } else {
-                       ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
-                                     inet->saddr);
-                       ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
-                                     inet->rcv_saddr);
+                       ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
+                       ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
+                                              &np->rcv_saddr);
                }
 
                return err;
@@ -243,8 +242,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        ipv6_addr_copy(&fl.fl6_src,
                       (saddr ? saddr : &np->saddr));
        fl.oif = sk->sk_bound_dev_if;
+       fl.mark = sk->sk_mark;
        fl.fl_ip_dport = usin->sin6_port;
-       fl.fl_ip_sport = inet->sport;
+       fl.fl_ip_sport = inet->inet_sport;
 
        if (np->opt && np->opt->srcrt) {
                struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
@@ -276,7 +276,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 
        /* set the source address */
        ipv6_addr_copy(&np->saddr, saddr);
-       inet->rcv_saddr = LOOPBACK4_IPV6;
+       inet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
        sk->sk_gso_type = SKB_GSO_TCPV6;
        __ip6_dst_store(sk, dst, NULL, NULL);
@@ -288,7 +288,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 
        tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
-       inet->dport = usin->sin6_port;
+       inet->inet_dport = usin->sin6_port;
 
        tcp_set_state(sk, TCP_SYN_SENT);
        err = inet6_hash_connect(&tcp_death_row, sk);
@@ -298,8 +298,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (!tp->write_seq)
                tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
                                                             np->daddr.s6_addr32,
-                                                            inet->sport,
-                                                            inet->dport);
+                                                            inet->inet_sport,
+                                                            inet->inet_dport);
 
        err = tcp_connect(sk);
        if (err)
@@ -311,7 +311,7 @@ late_failure:
        tcp_set_state(sk, TCP_CLOSE);
        __sk_dst_reset(sk);
 failure:
-       inet->dport = 0;
+       inet->inet_dport = 0;
        sk->sk_route_caps = 0;
        return err;
 }
@@ -383,8 +383,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                        ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
                        ipv6_addr_copy(&fl.fl6_src, &np->saddr);
                        fl.oif = sk->sk_bound_dev_if;
-                       fl.fl_ip_dport = inet->dport;
-                       fl.fl_ip_sport = inet->sport;
+                       fl.mark = sk->sk_mark;
+                       fl.fl_ip_dport = inet->inet_dport;
+                       fl.fl_ip_sport = inet->inet_sport;
                        security_skb_classify_flow(skb, &fl);
 
                        if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
@@ -477,6 +478,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
        ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
        fl.fl6_flowlabel = 0;
        fl.oif = treq->iif;
+       fl.mark = sk->sk_mark;
        fl.fl_ip_dport = inet_rsk(req)->rmt_port;
        fl.fl_ip_sport = inet_rsk(req)->loc_port;
        security_req_classify_flow(req, &fl);
@@ -591,7 +593,7 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
                        }
                        sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
                }
-               if (tcp_alloc_md5sig_pool() == NULL) {
+               if (tcp_alloc_md5sig_pool(sk) == NULL) {
                        kfree(newkey);
                        return -ENOMEM;
                }
@@ -1003,6 +1005,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
        skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
 
        t1 = (struct tcphdr *) skb_push(buff, tot_len);
+       skb_reset_transport_header(skb);
 
        /* Swap the send and the receive. */
        memset(t1, 0, sizeof(*t1));
@@ -1164,6 +1167,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
        struct request_sock *req = NULL;
        __u32 isn = TCP_SKB_CB(skb)->when;
+       struct dst_entry *dst = __sk_dst_get(sk);
 #ifdef CONFIG_SYN_COOKIES
        int want_cookie = 0;
 #else
@@ -1202,7 +1206,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
        tmp_opt.user_mss = tp->rx_opt.user_mss;
 
-       tcp_parse_options(skb, &tmp_opt, 0);
+       tcp_parse_options(skb, &tmp_opt, 0, dst);
 
        if (want_cookie && !tmp_opt.saw_tstamp)
                tcp_clear_options(&tmp_opt);
@@ -1289,11 +1293,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
                memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
-               ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
-                             newinet->daddr);
+               ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr);
 
-               ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
-                             newinet->saddr);
+               ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
 
                ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
 
@@ -1344,6 +1346,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                }
                ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
                fl.oif = sk->sk_bound_dev_if;
+               fl.mark = sk->sk_mark;
                fl.fl_ip_dport = inet_rsk(req)->rmt_port;
                fl.fl_ip_sport = inet_rsk(req)->loc_port;
                security_req_classify_flow(req, &fl);
@@ -1430,7 +1433,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
        tcp_initialize_rcv_mss(newsk);
 
-       newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
+       newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
+       newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
 #ifdef CONFIG_TCP_MD5SIG
        /* Copy over the MD5 key from the original socket */
@@ -1760,7 +1764,7 @@ static int tcp_v6_remember_stamp(struct sock *sk)
        return 0;
 }
 
-static struct inet_connection_sock_af_ops ipv6_specific = {
+static const struct inet_connection_sock_af_ops ipv6_specific = {
        .queue_xmit        = inet6_csk_xmit,
        .send_check        = tcp_v6_send_check,
        .rebuild_header    = inet6_sk_rebuild_header,
@@ -1792,7 +1796,7 @@ static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
  *     TCP over IPv4 via INET6 API
  */
 
-static struct inet_connection_sock_af_ops ipv6_mapped = {
+static const struct inet_connection_sock_af_ops ipv6_mapped = {
        .queue_xmit        = ip_queue_xmit,
        .send_check        = tcp_v4_send_check,
        .rebuild_header    = inet_sk_rebuild_header,
@@ -1845,7 +1849,7 @@ static int tcp_v6_init_sock(struct sock *sk)
        /* See draft-stevens-tcpca-spec-01 for discussion of the
         * initialization of these values.
         */
-       tp->snd_ssthresh = 0x7fffffff;
+       tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_clamp = ~0;
        tp->mss_cache = 536;
 
@@ -1930,8 +1934,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
 
        dest  = &np->daddr;
        src   = &np->rcv_saddr;
-       destp = ntohs(inet->dport);
-       srcp  = ntohs(inet->sport);
+       destp = ntohs(inet->inet_dport);
+       srcp  = ntohs(inet->inet_sport);
 
        if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
                timer_active    = 1;
@@ -1968,7 +1972,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
                   jiffies_to_clock_t(icsk->icsk_rto),
                   jiffies_to_clock_t(icsk->icsk_ack.ato),
                   (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
-                  tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
+                  tp->snd_cwnd,
+                  tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh
                   );
 }
 
@@ -2092,7 +2097,7 @@ struct proto tcpv6_prot = {
 #endif
 };
 
-static struct inet6_protocol tcpv6_protocol = {
+static const struct inet6_protocol tcpv6_protocol = {
        .handler        =       tcp_v6_rcv,
        .err_handler    =       tcp_v6_err,
        .gso_send_check =       tcp_v6_gso_send_check,