Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4325

kernel-2.6.18-194.11.1.el5.src.rpm

From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 24 Apr 2008 11:15:16 +0800
Subject: [xen] netfront: send fake arp when link gets carrier
Message-id: 20080424031516.GA6438@gondor.apana.org.au
O-Subject: [RHEL5.3 PATCH] [XEN] netfront: Send fake arp when link gets carrier
Bugzilla: 441716

Hi:

RHEL5.3 BZ 441716

[XEN] netfront: Send fake arp when link gets carrier

As it is the Xen netfront driver will transmit a fake ARP when the link gets an
IP address and when the link is brought up administratively.  However, this
overlooks the case when the first two events occur without a link carrier.
Thus to be sure that the packet makes it out we also need to attempt a transmit
when the carrier comes up which can be detected through the NETDEV_CHANGE
event.

This is what this patch does.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--

Acked-by: Don Dutile <ddutile@redhat.com>

diff --git a/drivers/xen/netfront/netfront.c b/drivers/xen/netfront/netfront.c
index 8925e77..ce9c1cf 100644
--- a/drivers/xen/netfront/netfront.c
+++ b/drivers/xen/netfront/netfront.c
@@ -1999,6 +1999,22 @@ inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
 	return NOTIFY_DONE;
 }
 
+/*
+ * We also send a fake ARP if the link gets carrier.
+ */
+static int
+netdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+
+	/* Carrier up event and is it one of our devices? */
+	if (event == NETDEV_CHANGE && netif_carrier_ok(dev) &&
+	    dev->open == network_open)
+		(void)send_fake_arp(dev);
+
+	return NOTIFY_DONE;
+}
+
 
 static void netif_disconnect_backend(struct netfront_info *info)
 {
@@ -2062,6 +2078,10 @@ static struct notifier_block notifier_inetdev = {
 	.priority       = 0
 };
 
+static struct notifier_block notifier_netdev = {
+	.notifier_call  = netdev_notify,
+};
+
 static int __init netif_init(void)
 {
 	if (!is_running_on_xen())
@@ -2083,6 +2103,7 @@ static int __init netif_init(void)
 	IPRINTK("Initialising virtual ethernet driver.\n");
 
 	(void)register_inetaddr_notifier(&notifier_inetdev);
+	(void)register_netdevice_notifier(&notifier_netdev);
 
 	return xenbus_register_frontend(&netfront);
 }
@@ -2096,6 +2117,7 @@ static void __exit netif_exit(void)
 	if (is_initial_xendomain())
 		return;
 
+	unregister_netdevice_notifier(&notifier_netdev);
 	unregister_inetaddr_notifier(&notifier_inetdev);
 
 	return xenbus_unregister_driver(&netfront);