aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishna Kumar <krkumar2@in.ibm.com>2009-10-19 19:46:45 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-20 21:55:46 -0400
commitea94ff3b55188df157a8740bdf3976a87563d705 (patch)
treea124cd047f8ed18c27aace29eafd2b343575857a
parentf04c8276248d3dd3e15a9a72f9711ba5e4069049 (diff)
net: Fix for dst_negative_advice
dst_negative_advice() should check for changed dst and reset sk_tx_queue_mapping accordingly. Pass sock to the callers of dst_negative_advice. (sk_reset_txq is defined just for use by dst_negative_advice. The only way I could find to get around this is to move dst_negative_() from dst.h to dst.c, include sock.h in dst.c, etc) Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/dst.h12
-rw-r--r--net/core/sock.c6
-rw-r--r--net/dccp/timer.c4
-rw-r--r--net/decnet/af_decnet.c2
-rw-r--r--net/ipv4/tcp_timer.c4
5 files changed, 21 insertions, 7 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index 5a900ddcf10d..720d90653a8e 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -222,11 +222,19 @@ static inline void dst_confirm(struct dst_entry *dst)
222 neigh_confirm(dst->neighbour); 222 neigh_confirm(dst->neighbour);
223} 223}
224 224
225static inline void dst_negative_advice(struct dst_entry **dst_p) 225static inline void dst_negative_advice(struct dst_entry **dst_p,
226 struct sock *sk)
226{ 227{
227 struct dst_entry * dst = *dst_p; 228 struct dst_entry * dst = *dst_p;
228 if (dst && dst->ops->negative_advice) 229 if (dst && dst->ops->negative_advice) {
229 *dst_p = dst->ops->negative_advice(dst); 230 *dst_p = dst->ops->negative_advice(dst);
231
232 if (dst != *dst_p) {
233 extern void sk_reset_txq(struct sock *sk);
234
235 sk_reset_txq(sk);
236 }
237 }
230} 238}
231 239
232static inline void dst_link_failure(struct sk_buff *skb) 240static inline void dst_link_failure(struct sk_buff *skb)
diff --git a/net/core/sock.c b/net/core/sock.c
index 934d9673f084..5a51512f638a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -352,6 +352,12 @@ discard_and_relse:
352} 352}
353EXPORT_SYMBOL(sk_receive_skb); 353EXPORT_SYMBOL(sk_receive_skb);
354 354
355void sk_reset_txq(struct sock *sk)
356{
357 sk_tx_queue_clear(sk);
358}
359EXPORT_SYMBOL(sk_reset_txq);
360
355struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) 361struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
356{ 362{
357 struct dst_entry *dst = sk->sk_dst_cache; 363 struct dst_entry *dst = sk->sk_dst_cache;
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 162d1e683c39..bbfeb5eae46a 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -38,7 +38,7 @@ static int dccp_write_timeout(struct sock *sk)
38 38
39 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) { 39 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
40 if (icsk->icsk_retransmits != 0) 40 if (icsk->icsk_retransmits != 0)
41 dst_negative_advice(&sk->sk_dst_cache); 41 dst_negative_advice(&sk->sk_dst_cache, sk);
42 retry_until = icsk->icsk_syn_retries ? 42 retry_until = icsk->icsk_syn_retries ?
43 : sysctl_dccp_request_retries; 43 : sysctl_dccp_request_retries;
44 } else { 44 } else {
@@ -63,7 +63,7 @@ static int dccp_write_timeout(struct sock *sk)
63 Golden words :-). 63 Golden words :-).
64 */ 64 */
65 65
66 dst_negative_advice(&sk->sk_dst_cache); 66 dst_negative_advice(&sk->sk_dst_cache, sk);
67 } 67 }
68 68
69 retry_until = sysctl_dccp_retries2; 69 retry_until = sysctl_dccp_retries2;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 4d3060660a14..664965c87e16 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1955,7 +1955,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1955 } 1955 }
1956 1956
1957 if ((flags & MSG_TRYHARD) && sk->sk_dst_cache) 1957 if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
1958 dst_negative_advice(&sk->sk_dst_cache); 1958 dst_negative_advice(&sk->sk_dst_cache, sk);
1959 1959
1960 mss = scp->segsize_rem; 1960 mss = scp->segsize_rem;
1961 fctype = scp->services_rem & NSP_FC_MASK; 1961 fctype = scp->services_rem & NSP_FC_MASK;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 6e8996cb79d0..8353a538cd4c 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -141,14 +141,14 @@ static int tcp_write_timeout(struct sock *sk)
141 141
142 if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { 142 if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
143 if (icsk->icsk_retransmits) 143 if (icsk->icsk_retransmits)
144 dst_negative_advice(&sk->sk_dst_cache); 144 dst_negative_advice(&sk->sk_dst_cache, sk);
145 retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; 145 retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
146 } else { 146 } else {
147 if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { 147 if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
148 /* Black hole detection */ 148 /* Black hole detection */
149 tcp_mtu_probing(icsk, sk); 149 tcp_mtu_probing(icsk, sk);
150 150
151 dst_negative_advice(&sk->sk_dst_cache); 151 dst_negative_advice(&sk->sk_dst_cache, sk);
152 } 152 }
153 153
154 retry_until = sysctl_tcp_retries2; 154 retry_until = sysctl_tcp_retries2;