[INET]: Introduce inet_sk_rebuild_header
[deliverable/linux.git] / net / ipv4 / tcp_ipv4.c
index 62f62bb05c2ae479eae4c03ee2986fd43e20b9a4..ae6fad99a9a99707d769c274db8b10067b0f20de 100644 (file)
@@ -242,9 +242,14 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
                tcp_port_rover = rover;
                spin_unlock(&tcp_portalloc_lock);
 
-               /* Exhausted local port range during search? */
+               /* Exhausted local port range during search?  It is not
+                * possible for us to be holding one of the bind hash
+                * locks if this test triggers, because if 'remaining'
+                * drops to zero, we broke out of the do/while loop at
+                * the top level, not from the 'break;' statement.
+                */
                ret = 1;
-               if (remaining <= 0)
+               if (unlikely(remaining <= 0))
                        goto fail;
 
                /* OK, here is the one we will use.  HEAD is
@@ -832,8 +837,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                goto failure;
 
        /* OK, now commit destination to socket.  */
-       __sk_dst_set(sk, &rt->u.dst);
-       tcp_v4_setup_caps(sk, &rt->u.dst);
+       sk_setup_caps(sk, &rt->u.dst);
 
        if (!tp->write_seq)
                tp->write_seq = secure_tcp_sequence_number(inet->saddr,
@@ -1494,12 +1498,11 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
                         * to destinations, already remembered
                         * to the moment of synflood.
                         */
-                       NETDEBUG(if (net_ratelimit()) \
-                                       printk(KERN_DEBUG "TCP: drop open "
-                                                         "request from %u.%u."
-                                                         "%u.%u/%u\n", \
-                                              NIPQUAD(saddr),
-                                              ntohs(skb->h.th->source)));
+                       LIMIT_NETDEBUG(printk(KERN_DEBUG "TCP: drop open "
+                                             "request from %u.%u."
+                                             "%u.%u/%u\n",
+                                             NIPQUAD(saddr),
+                                             ntohs(skb->h.th->source)));
                        dst_release(dst);
                        goto drop_and_free;
                }
@@ -1549,8 +1552,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        if (!newsk)
                goto exit;
 
-       newsk->sk_dst_cache = dst;
-       tcp_v4_setup_caps(newsk, dst);
+       sk_setup_caps(newsk, dst);
 
        newtp                 = tcp_sk(newsk);
        newinet               = inet_sk(newsk);
@@ -1627,8 +1629,7 @@ static int tcp_v4_checksum_init(struct sk_buff *skb)
                                  skb->nh.iph->daddr, skb->csum))
                        return 0;
 
-               NETDEBUG(if (net_ratelimit())
-                               printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+               LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
                skb->ip_summed = CHECKSUM_NONE;
        }
        if (skb->len <= 76) {
@@ -1831,112 +1832,6 @@ do_time_wait:
        goto discard_it;
 }
 
-/* With per-bucket locks this operation is not-atomic, so that
- * this version is not worse.
- */
-static void __tcp_v4_rehash(struct sock *sk)
-{
-       sk->sk_prot->unhash(sk);
-       sk->sk_prot->hash(sk);
-}
-
-static int tcp_v4_reselect_saddr(struct sock *sk)
-{
-       struct inet_sock *inet = inet_sk(sk);
-       int err;
-       struct rtable *rt;
-       __u32 old_saddr = inet->saddr;
-       __u32 new_saddr;
-       __u32 daddr = inet->daddr;
-
-       if (inet->opt && inet->opt->srr)
-               daddr = inet->opt->faddr;
-
-       /* Query new route. */
-       err = ip_route_connect(&rt, daddr, 0,
-                              RT_CONN_FLAGS(sk),
-                              sk->sk_bound_dev_if,
-                              IPPROTO_TCP,
-                              inet->sport, inet->dport, sk);
-       if (err)
-               return err;
-
-       __sk_dst_set(sk, &rt->u.dst);
-       tcp_v4_setup_caps(sk, &rt->u.dst);
-
-       new_saddr = rt->rt_src;
-
-       if (new_saddr == old_saddr)
-               return 0;
-
-       if (sysctl_ip_dynaddr > 1) {
-               printk(KERN_INFO "tcp_v4_rebuild_header(): shifting inet->"
-                                "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",
-                      NIPQUAD(old_saddr),
-                      NIPQUAD(new_saddr));
-       }
-
-       inet->saddr = new_saddr;
-       inet->rcv_saddr = new_saddr;
-
-       /* XXX The only one ugly spot where we need to
-        * XXX really change the sockets identity after
-        * XXX it has entered the hashes. -DaveM
-        *
-        * Besides that, it does not check for connection
-        * uniqueness. Wait for troubles.
-        */
-       __tcp_v4_rehash(sk);
-       return 0;
-}
-
-int tcp_v4_rebuild_header(struct sock *sk)
-{
-       struct inet_sock *inet = inet_sk(sk);
-       struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
-       u32 daddr;
-       int err;
-
-       /* Route is OK, nothing to do. */
-       if (rt)
-               return 0;
-
-       /* Reroute. */
-       daddr = inet->daddr;
-       if (inet->opt && inet->opt->srr)
-               daddr = inet->opt->faddr;
-
-       {
-               struct flowi fl = { .oif = sk->sk_bound_dev_if,
-                                   .nl_u = { .ip4_u =
-                                             { .daddr = daddr,
-                                               .saddr = inet->saddr,
-                                               .tos = RT_CONN_FLAGS(sk) } },
-                                   .proto = IPPROTO_TCP,
-                                   .uli_u = { .ports =
-                                              { .sport = inet->sport,
-                                                .dport = inet->dport } } };
-                                               
-               err = ip_route_output_flow(&rt, &fl, sk, 0);
-       }
-       if (!err) {
-               __sk_dst_set(sk, &rt->u.dst);
-               tcp_v4_setup_caps(sk, &rt->u.dst);
-               return 0;
-       }
-
-       /* Routing failed... */
-       sk->sk_route_caps = 0;
-
-       if (!sysctl_ip_dynaddr ||
-           sk->sk_state != TCP_SYN_SENT ||
-           (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
-           (err = tcp_v4_reselect_saddr(sk)) != 0)
-               sk->sk_err_soft = -err;
-
-       return err;
-}
-
 static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
 {
        struct sockaddr_in *sin = (struct sockaddr_in *) uaddr;
@@ -2008,7 +1903,7 @@ int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw)
 struct tcp_func ipv4_specific = {
        .queue_xmit     =       ip_queue_xmit,
        .send_check     =       tcp_v4_send_check,
-       .rebuild_header =       tcp_v4_rebuild_header,
+       .rebuild_header =       inet_sk_rebuild_header,
        .conn_request   =       tcp_v4_conn_request,
        .syn_recv_sock  =       tcp_v4_syn_recv_sock,
        .remember_stamp =       tcp_v4_remember_stamp,
@@ -2640,7 +2535,6 @@ EXPORT_SYMBOL(tcp_unhash);
 EXPORT_SYMBOL(tcp_v4_conn_request);
 EXPORT_SYMBOL(tcp_v4_connect);
 EXPORT_SYMBOL(tcp_v4_do_rcv);
-EXPORT_SYMBOL(tcp_v4_rebuild_header);
 EXPORT_SYMBOL(tcp_v4_remember_stamp);
 EXPORT_SYMBOL(tcp_v4_send_check);
 EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
This page took 0.026997 seconds and 5 git commands to generate.