summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDuan Jiong <duanj.fnst@cn.fujitsu.com>2014-05-09 13:16:48 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-31 13:20:37 -0700
commitc712c1f79c8e074cb4568231c3b034519896108d (patch)
treed2a5e79b0cb732e1722cac9679f368589201672d /net
parenta3db451d65cb1b0195ebf19798811963b30173ea (diff)
downloadlinux-stable-c712c1f79c8e074cb4568231c3b034519896108d.tar.gz
linux-stable-c712c1f79c8e074cb4568231c3b034519896108d.tar.bz2
linux-stable-c712c1f79c8e074cb4568231c3b034519896108d.zip
neigh: set nud_state to NUD_INCOMPLETE when probing router reachability
[ Upstream commit 2176d5d41891753774f648b67470398a5acab584 ] Since commit 7e98056964("ipv6: router reachability probing"), a router falls into NUD_FAILED will be probed. Now if function rt6_select() selects a router which neighbour state is NUD_FAILED, and at the same time function rt6_probe() changes the neighbour state to NUD_PROBE, then function dst_neigh_output() can directly send packets, but actually the neighbour still is unreachable. If we set nud_state to NUD_INCOMPLETE instead NUD_PROBE, packets will not be sent out until the neihbour is reachable. In addition, because the route should be probes with a single NS, so we must set neigh->probes to neigh_max_probes(), then the neigh timer timeout and function neigh_timer_handler() will not send other NS Messages. Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/core/neighbour.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e16129019c66..7d95f69635c6 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1247,8 +1247,8 @@ void __neigh_set_probe_once(struct neighbour *neigh)
neigh->updated = jiffies;
if (!(neigh->nud_state & NUD_FAILED))
return;
- neigh->nud_state = NUD_PROBE;
- atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES));
+ neigh->nud_state = NUD_INCOMPLETE;
+ atomic_set(&neigh->probes, neigh_max_probes(neigh));
neigh_add_timer(neigh,
jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME));
}