net: add ARP notify option for devices

This adds another inet device option to enable gratuitous ARP
when device is brought up or address change. This is handy for
clusters or virtualization.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Stephen Hemminger 2009-02-01 01:04:33 -08:00 committed by David S. Miller
parent ead731837d
commit eefef1cf76
5 changed files with 18 additions and 0 deletions

View file

@ -782,6 +782,12 @@ arp_ignore - INTEGER
The max value from conf/{all,interface}/arp_ignore is used The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface} when ARP request is received on the {interface}
arp_notify - BOOLEAN
Define mode for notification of address and device changes.
0 - (default): do nothing
1 - Generate gratuitous arp replies when device is brought up
or hardware address changes.
arp_accept - BOOLEAN arp_accept - BOOLEAN
Define behavior when gratuitous arp replies are received: Define behavior when gratuitous arp replies are received:
0 - drop gratuitous arp frames 0 - drop gratuitous arp frames

View file

@ -108,6 +108,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
#define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER) #define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER)
#define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
#define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
#define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
struct in_ifaddr struct in_ifaddr
{ {

View file

@ -490,6 +490,7 @@ enum
NET_IPV4_CONF_ARP_IGNORE=19, NET_IPV4_CONF_ARP_IGNORE=19,
NET_IPV4_CONF_PROMOTE_SECONDARIES=20, NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
NET_IPV4_CONF_ARP_ACCEPT=21, NET_IPV4_CONF_ARP_ACCEPT=21,
NET_IPV4_CONF_ARP_NOTIFY=22,
__NET_IPV4_CONF_MAX __NET_IPV4_CONF_MAX
}; };

View file

@ -219,6 +219,7 @@ static const struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
{ NET_IPV4_CONF_ARP_IGNORE, "arp_ignore" }, { NET_IPV4_CONF_ARP_IGNORE, "arp_ignore" },
{ NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" }, { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" },
{ NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" }, { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" },
{ NET_IPV4_CONF_ARP_NOTIFY, "arp_notify" },
{} {}
}; };

View file

@ -1075,6 +1075,14 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
} }
} }
ip_mc_up(in_dev); ip_mc_up(in_dev);
/* fall through */
case NETDEV_CHANGEADDR:
if (IN_DEV_ARP_NOTIFY(in_dev))
arp_send(ARPOP_REQUEST, ETH_P_ARP,
in_dev->ifa_list->ifa_address,
dev,
in_dev->ifa_list->ifa_address,
NULL, dev->dev_addr, NULL);
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
ip_mc_down(in_dev); ip_mc_down(in_dev);
@ -1439,6 +1447,7 @@ static struct devinet_sysctl_table {
DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"), DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"), DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),