diff options
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bcf9bb508200..1d4cd3b4fd69 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -412,8 +412,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
412 | "HHUptod\tSpecDst"); | 412 | "HHUptod\tSpecDst"); |
413 | else { | 413 | else { |
414 | struct rtable *r = v; | 414 | struct rtable *r = v; |
415 | struct neighbour *n; | ||
415 | int len; | 416 | int len; |
416 | 417 | ||
418 | n = dst_get_neighbour(&r->dst); | ||
417 | seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t" | 419 | seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t" |
418 | "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", | 420 | "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", |
419 | r->dst.dev ? r->dst.dev->name : "*", | 421 | r->dst.dev ? r->dst.dev->name : "*", |
@@ -427,9 +429,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
427 | dst_metric(&r->dst, RTAX_RTTVAR)), | 429 | dst_metric(&r->dst, RTAX_RTTVAR)), |
428 | r->rt_key_tos, | 430 | r->rt_key_tos, |
429 | -1, | 431 | -1, |
430 | (r->dst.neighbour && | 432 | (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0, |
431 | (r->dst.neighbour->nud_state & NUD_CONNECTED)) ? | ||
432 | 1 : 0, | ||
433 | r->rt_spec_dst, &len); | 433 | r->rt_spec_dst, &len); |
434 | 434 | ||
435 | seq_printf(seq, "%*s\n", 127 - len, ""); | 435 | seq_printf(seq, "%*s\n", 127 - len, ""); |
@@ -1026,7 +1026,7 @@ static int rt_bind_neighbour(struct rtable *rt) | |||
1026 | n = ipv4_neigh_lookup(tbl, dev, nexthop); | 1026 | n = ipv4_neigh_lookup(tbl, dev, nexthop); |
1027 | if (IS_ERR(n)) | 1027 | if (IS_ERR(n)) |
1028 | return PTR_ERR(n); | 1028 | return PTR_ERR(n); |
1029 | rt->dst.neighbour = n; | 1029 | dst_set_neighbour(&rt->dst, n); |
1030 | 1030 | ||
1031 | return 0; | 1031 | return 0; |
1032 | } | 1032 | } |
@@ -1617,23 +1617,24 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
1617 | { | 1617 | { |
1618 | struct rtable *rt = (struct rtable *) dst; | 1618 | struct rtable *rt = (struct rtable *) dst; |
1619 | __be32 orig_gw = rt->rt_gateway; | 1619 | __be32 orig_gw = rt->rt_gateway; |
1620 | struct neighbour *n; | ||
1620 | 1621 | ||
1621 | dst_confirm(&rt->dst); | 1622 | dst_confirm(&rt->dst); |
1622 | 1623 | ||
1623 | neigh_release(rt->dst.neighbour); | 1624 | neigh_release(dst_get_neighbour(&rt->dst)); |
1624 | rt->dst.neighbour = NULL; | 1625 | dst_set_neighbour(&rt->dst, NULL); |
1625 | 1626 | ||
1626 | rt->rt_gateway = peer->redirect_learned.a4; | 1627 | rt->rt_gateway = peer->redirect_learned.a4; |
1627 | if (rt_bind_neighbour(rt) || | 1628 | rt_bind_neighbour(rt); |
1628 | !(rt->dst.neighbour->nud_state & NUD_VALID)) { | 1629 | n = dst_get_neighbour(&rt->dst); |
1629 | if (rt->dst.neighbour) | 1630 | if (!n || !(n->nud_state & NUD_VALID)) { |
1630 | neigh_event_send(rt->dst.neighbour, NULL); | 1631 | if (n) |
1632 | neigh_event_send(n, NULL); | ||
1631 | rt->rt_gateway = orig_gw; | 1633 | rt->rt_gateway = orig_gw; |
1632 | return -EAGAIN; | 1634 | return -EAGAIN; |
1633 | } else { | 1635 | } else { |
1634 | rt->rt_flags |= RTCF_REDIRECTED; | 1636 | rt->rt_flags |= RTCF_REDIRECTED; |
1635 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, | 1637 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); |
1636 | rt->dst.neighbour); | ||
1637 | } | 1638 | } |
1638 | return 0; | 1639 | return 0; |
1639 | } | 1640 | } |