提交 c3a2e837 编写于 作者: J Julian Anastasov 提交者: David S. Miller

tcp: replace dst_confirm with sk_dst_confirm

When same struct dst_entry can be used for many different
neighbours we can not use it for pending confirmations.
Use the new sk_dst_confirm() helper to propagate the
indication from received packets to sock_confirm_neigh().
Reported-by: NYueHaibing <yuehaibing@huawei.com>
Fixes: 5110effe ("net: Do delayed neigh confirmation.")
Fixes: f2bb4bed ("ipv4: Cache output routes in fib_info nexthops.")
Tested-by: NYueHaibing <yuehaibing@huawei.com>
Signed-off-by: NJulian Anastasov <ja@ssi.bg>
Acked-by: NEric Dumazet <edumazet@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 c86a773c
...@@ -3644,11 +3644,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) ...@@ -3644,11 +3644,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
if (tp->tlp_high_seq) if (tp->tlp_high_seq)
tcp_process_tlp_ack(sk, ack, flag); tcp_process_tlp_ack(sk, ack, flag);
if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) { if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP))
struct dst_entry *dst = __sk_dst_get(sk); sk_dst_confirm(sk);
if (dst)
dst_confirm(dst);
}
if (icsk->icsk_pending == ICSK_TIME_RETRANS) if (icsk->icsk_pending == ICSK_TIME_RETRANS)
tcp_schedule_loss_probe(sk); tcp_schedule_loss_probe(sk);
...@@ -5995,7 +5992,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -5995,7 +5992,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
break; break;
case TCP_FIN_WAIT1: { case TCP_FIN_WAIT1: {
struct dst_entry *dst;
int tmo; int tmo;
/* If we enter the TCP_FIN_WAIT1 state and we are a /* If we enter the TCP_FIN_WAIT1 state and we are a
...@@ -6022,9 +6018,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -6022,9 +6018,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
tcp_set_state(sk, TCP_FIN_WAIT2); tcp_set_state(sk, TCP_FIN_WAIT2);
sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_shutdown |= SEND_SHUTDOWN;
dst = __sk_dst_get(sk); sk_dst_confirm(sk);
if (dst)
dst_confirm(dst);
if (!sock_flag(sk, SOCK_DEAD)) { if (!sock_flag(sk, SOCK_DEAD)) {
/* Wake up lingering close() */ /* Wake up lingering close() */
......
...@@ -375,12 +375,10 @@ void tcp_update_metrics(struct sock *sk) ...@@ -375,12 +375,10 @@ void tcp_update_metrics(struct sock *sk)
u32 val; u32 val;
int m; int m;
sk_dst_confirm(sk);
if (sysctl_tcp_nometrics_save || !dst) if (sysctl_tcp_nometrics_save || !dst)
return; return;
if (dst->flags & DST_HOST)
dst_confirm(dst);
rcu_read_lock(); rcu_read_lock();
if (icsk->icsk_backoff || !tp->srtt_us) { if (icsk->icsk_backoff || !tp->srtt_us) {
/* This session failed to estimate rtt. Why? /* This session failed to estimate rtt. Why?
...@@ -493,11 +491,10 @@ void tcp_init_metrics(struct sock *sk) ...@@ -493,11 +491,10 @@ void tcp_init_metrics(struct sock *sk)
struct tcp_metrics_block *tm; struct tcp_metrics_block *tm;
u32 val, crtt = 0; /* cached RTT scaled by 8 */ u32 val, crtt = 0; /* cached RTT scaled by 8 */
sk_dst_confirm(sk);
if (!dst) if (!dst)
goto reset; goto reset;
dst_confirm(dst);
rcu_read_lock(); rcu_read_lock();
tm = tcp_get_metrics(sk, dst, true); tm = tcp_get_metrics(sk, dst, true);
if (!tm) { if (!tm) {
......
...@@ -980,6 +980,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, ...@@ -980,6 +980,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
skb_set_hash_from_sk(skb, sk); skb_set_hash_from_sk(skb, sk);
atomic_add(skb->truesize, &sk->sk_wmem_alloc); atomic_add(skb->truesize, &sk->sk_wmem_alloc);
skb_set_dst_pending_confirm(skb, sk->sk_dst_pending_confirm);
/* Build TCP header and checksum it. */ /* Build TCP header and checksum it. */
th = (struct tcphdr *)skb->data; th = (struct tcphdr *)skb->data;
th->source = inet->inet_sport; th->source = inet->inet_sport;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册