arp_notify: allow drivers to explicitly request a notification event.
authorIan Campbell <Ian.Campbell@citrix.com>
Wed, 26 May 2010 00:09:42 +0000 (00:09 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 31 May 2010 07:27:44 +0000 (00:27 -0700)
Currently such notifications are only generated when the device comes up or the
address changes. However one use case for these notifications is to enable
faster network recovery after a virtual machine migration (by causing switches
to relearn their MAC tables). A migration appears to the network stack as a
temporary loss of carrier and therefore does not trigger either of the current
conditions. Rather than adding carrier up as a trigger (which can cause issues
when interfaces a flapping) simply add an interface which the driver can use
to explicitly trigger the notification.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Stephen Hemminger <shemminger@linux-foundation.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: stable@kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
include/linux/notifier.h
net/ipv4/devinet.c
net/sched/sch_generic.c

index 40291f3750247dfa12102178a6aed457e7735516..a24916156f4e69f50a912d061f17726d2e2a8af2 100644 (file)
@@ -1772,6 +1772,8 @@ extern void netif_carrier_on(struct net_device *dev);
 
 extern void netif_carrier_off(struct net_device *dev);
 
+extern void netif_notify_peers(struct net_device *dev);
+
 /**
  *     netif_dormant_on - mark device as dormant.
  *     @dev: network device
index 540703b555cb2be4bbea2d8e7f0b84d96ca3b474..22c2abb619740b39712ac12ae0030dc6f8cf1a0e 100644 (file)
@@ -210,6 +210,7 @@ static inline int notifier_to_errno(int ret)
 #define NETDEV_POST_INIT       0x0010
 #define NETDEV_UNREGISTER_BATCH 0x0011
 #define NETDEV_BONDING_DESLAVE  0x0012
+#define NETDEV_NOTIFY_PEERS    0x0012
 
 #define SYS_DOWN       0x0001  /* Notify of system down */
 #define SYS_RESTART    SYS_DOWN
index 382bc768ed565cc79bc79c8c71fa0588d2a7a78b..da14c49284f41677f17d273badbbbd0560381ddb 100644 (file)
@@ -1081,6 +1081,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
                }
                ip_mc_up(in_dev);
                /* fall through */
+       case NETDEV_NOTIFY_PEERS:
        case NETDEV_CHANGEADDR:
                /* Send gratuitous ARP to notify of link change */
                if (IN_DEV_ARP_NOTIFY(in_dev)) {
index a63029ef3eddc9e1bc19cbc552f327e6fdafa8aa..bd1892fe4b213c16cb705ebf7f3aee80242eebe2 100644 (file)
@@ -327,6 +327,24 @@ void netif_carrier_off(struct net_device *dev)
 }
 EXPORT_SYMBOL(netif_carrier_off);
 
+/**
+ *     netif_notify_peers - notify network peers about existence of @dev
+ *     @dev: network device
+ *
+ * Generate traffic such that interested network peers are aware of
+ * @dev, such as by generating a gratuitous ARP. This may be used when
+ * a device wants to inform the rest of the network about some sort of
+ * reconfiguration such as a failover event or virtual machine
+ * migration.
+ */
+void netif_notify_peers(struct net_device *dev)
+{
+       rtnl_lock();
+       call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev);
+       rtnl_unlock();
+}
+EXPORT_SYMBOL(netif_notify_peers);
+
 /* "NOOP" scheduler: the best scheduler, recommended for all interfaces
    under all circumstances. It is difficult to invent anything faster or
    cheaper.