diff options
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1730689f560e..6afc4eb50591 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1628,16 +1628,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
1628 | { | 1628 | { |
1629 | struct rtable *rt = (struct rtable *) dst; | 1629 | struct rtable *rt = (struct rtable *) dst; |
1630 | __be32 orig_gw = rt->rt_gateway; | 1630 | __be32 orig_gw = rt->rt_gateway; |
1631 | struct neighbour *n; | 1631 | struct neighbour *n, *old_n; |
1632 | 1632 | ||
1633 | dst_confirm(&rt->dst); | 1633 | dst_confirm(&rt->dst); |
1634 | 1634 | ||
1635 | neigh_release(dst_get_neighbour(&rt->dst)); | ||
1636 | dst_set_neighbour(&rt->dst, NULL); | ||
1637 | |||
1638 | rt->rt_gateway = peer->redirect_learned.a4; | 1635 | rt->rt_gateway = peer->redirect_learned.a4; |
1639 | rt_bind_neighbour(rt); | 1636 | |
1640 | n = dst_get_neighbour(&rt->dst); | 1637 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); |
1638 | if (IS_ERR(n)) | ||
1639 | return PTR_ERR(n); | ||
1640 | old_n = xchg(&rt->dst._neighbour, n); | ||
1641 | if (old_n) | ||
1642 | neigh_release(old_n); | ||
1641 | if (!n || !(n->nud_state & NUD_VALID)) { | 1643 | if (!n || !(n->nud_state & NUD_VALID)) { |
1642 | if (n) | 1644 | if (n) |
1643 | neigh_event_send(n, NULL); | 1645 | neigh_event_send(n, NULL); |