diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 08174a2..7b1162b 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1185,6 +1185,8 @@ out: static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { + struct in_device *in_dev; + struct in_ifaddr *ifa; struct net_device *dev = ptr; if (dev->nd_net != &init_net) @@ -1194,6 +1196,22 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo case NETDEV_CHANGEADDR: neigh_changeaddr(&arp_tbl, dev); rt_cache_flush(0); + + /* Send gratuitous ARP to the neighbours to update their arp tables */ + + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev); + if (in_dev == NULL) + goto out; + for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) + arp_send(ARPOP_REQUEST, ETH_P_ARP, + ifa->ifa_address, + dev, + ifa->ifa_address, + NULL, dev->dev_addr, NULL); +out: + rcu_read_unlock(); + break; default: break;