diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-04-15 09:46:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-18 02:35:16 -0400 |
commit | f47b94646f30529624c82ab0f9cd5bd3f25ef9d2 (patch) | |
tree | ae691388f1cccb21449e6c9e14aa52c2388ad66f /net/ipv6/ndisc.c | |
parent | b3337e4cea15beb167e8d3a70ca1023e39abb4e5 (diff) |
ipv6: Send unsolicited neighbour advertismements when notified
The NETDEV_NOTIFY_PEERS notifier is a request to send such
advertisements following migration to a different physical link,
e.g. virtual machine migration.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f057ff312840..62cbd15b4cde 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -611,6 +611,29 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
611 | inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); | 611 | inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); |
612 | } | 612 | } |
613 | 613 | ||
614 | static void ndisc_send_unsol_na(struct net_device *dev) | ||
615 | { | ||
616 | struct inet6_dev *idev; | ||
617 | struct inet6_ifaddr *ifa; | ||
618 | struct in6_addr mcaddr; | ||
619 | |||
620 | idev = in6_dev_get(dev); | ||
621 | if (!idev) | ||
622 | return; | ||
623 | |||
624 | read_lock_bh(&idev->lock); | ||
625 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | ||
626 | addrconf_addr_solict_mult(&ifa->addr, &mcaddr); | ||
627 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, | ||
628 | /*router=*/ !!idev->cnf.forwarding, | ||
629 | /*solicited=*/ false, /*override=*/ true, | ||
630 | /*inc_opt=*/ true); | ||
631 | } | ||
632 | read_unlock_bh(&idev->lock); | ||
633 | |||
634 | in6_dev_put(idev); | ||
635 | } | ||
636 | |||
614 | void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, | 637 | void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, |
615 | const struct in6_addr *solicit, | 638 | const struct in6_addr *solicit, |
616 | const struct in6_addr *daddr, const struct in6_addr *saddr) | 639 | const struct in6_addr *daddr, const struct in6_addr *saddr) |
@@ -1723,6 +1746,9 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, | |||
1723 | neigh_ifdown(&nd_tbl, dev); | 1746 | neigh_ifdown(&nd_tbl, dev); |
1724 | fib6_run_gc(~0UL, net); | 1747 | fib6_run_gc(~0UL, net); |
1725 | break; | 1748 | break; |
1749 | case NETDEV_NOTIFY_PEERS: | ||
1750 | ndisc_send_unsol_na(dev); | ||
1751 | break; | ||
1726 | default: | 1752 | default: |
1727 | break; | 1753 | break; |
1728 | } | 1754 | } |