Patchwork [Xen-devel] xen-netback notify DomU to send ARP.

login
register
mail settings
Submitter jianhai luan
Date Jan. 9, 2013, 7:39 a.m.
Message ID <50ED1EB3.3080605@oracle.com>
Download mbox | patch
Permalink /patch/210638/
State RFC
Delegated to: David Miller
Headers show

Comments

jianhai luan - Jan. 9, 2013, 7:39 a.m.
Sorry,
   My attachment is wrong, please check the patch.

On 2013-1-9 0:00, Ian Campbell wrote:
> On Tue, 2013-01-08 at 15:40 +0000, jianhai luan wrote:
>> On 2013-1-8 21:42, Ian Campbell wrote:
>>> On Tue, 2013-01-08 at 13:13 +0000, Jan Beulich wrote:
>>>>>>> On 08.01.13 at 12:57, jianhai luan <jianhai.luan@oracle.com>
>>>>>>> wrote:
>>>>>      When Xen Dom0's network circumstance changed, DomU
>>>>> should be notified in some special condition. For
>>>>> example the below circumstance:
>>>>>      ping from Guest A to DomU:
>>>>>      Guest A --> eth0 - bond0 - xenbr0 --VIF(DOMU)
>>>>>                  eth1 /
>>>>>      when eth0 inactive, and eth1 active.
>>> How is eth0 failing? Are you unplugging it, un-enslaving it or
>>> taking
>>> some other sort of administrative action?
>> In my emulation environment, i unplug it or ifdown the interface,
> I expect these would behave rather different, since the affect of ifdown
> looks rather different to an unplug from the PoV of the switch.
>
> Is the ifdown case something which you are trying to solve or just what
> appeared to be a convenient test case? I'd be less inclined to worry
> about explict admin actions such as that.
>
> Unplugging the cable should cause:
>
>>> Doesn't this state change cause the switch to which eth0 and eth1
>>> are
>>> attached to forget the MAC tables associated with the eth0 port,
>>> meaning
>>> that subsequent traffic will be flooded until it learns that eth1 is
>>> the
>>> new port?
> Ian
>
>
From f1235377724b4363cba27ef8b29fb89e2b36189a Mon Sep 17 00:00:00 2001
From: Jason Luan <jianhai.luan@oracle.com>
Date: Fri, 28 Dec 2012 15:43:06 +0800
Subject: [PATCH] xen-netback notify DomU to send ARP.

When Xen Dom0's network circumstance changed, DomU
should be notified in some special condition. For
example the below circumstance:
  ping from Guest A to DomU:
  Guest A --> eth0 - bond0 - xenbr0 --VIF(DOMU)
              eth1 /
  when eth0 inactive, and eth1 active.
  Guest A --> eth0   bond0 - xenbr0 --VIF(DOMU)
              eth1 /
  Guest A will don't reach to DomU. After Guest A
  send ARP request and DomU respond, Guest A will
  reach DomU. But some more second will be elapsed.
              eth0   bond0 - xenbr0 --VIF(DOMU)
  Guest A --> eth1/

If Xen netback watch the network change, will notify
DomU by change it own status. So netfront will watch
netback's change, and DomU send ARP initiative.

Signed-off-by: Jason Luan <jianhai.luan@oracle.com>
---
 drivers/net/xen-netback/xenbus.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)
Jan Beulich - Jan. 9, 2013, 10:06 a.m.
>>> On 09.01.13 at 08:39, jianhai luan <jianhai.luan@oracle.com> wrote:
>@@ -34,11 +35,42 @@ static void connect(struct backend_info *);
> static void backend_create_xenvif(struct backend_info *be);
> static void unregister_hotplug_status_watch(struct backend_info *be);
> 
>+#define nb_to_backend(nb) container_of(nb, struct backend_info, vif_notifier)
>+/**
>+ * When network condition of vif change, notify the frontend.
>+ */
>+static int netback_netdev_event(struct notifier_block *this,
>+				unsigned long event, void *ptr)
>+{
>+	struct net_device *event_dev = (struct net_device *)ptr;

Pointless cast.

>+	struct backend_info *be = nb_to_backend(this);
>+
>+	pr_debug("event_dev: %s, event: %lx\n",
>+		 event_dev ? event_dev->name : "None", event);
>+
>+	if (!be->vif)
>+		goto out;
>+
>+	switch (event) {
>+	case NETDEV_NOTIFY_PEERS:
>+		/* Notify frontend to Send gratuitous ARP */
>+		xenbus_switch_state(be->dev, XenbusStateInitialised);
>+		xenbus_switch_state(be->dev, XenbusStateConnected);

This is the sort of change that clearly isn't acceptable, as I don't
think you have ways to check _all_ existing frontends for their
compatibility with this. A connected -> connected transition
might be acceptable (that was done in the block frontend too, for
implementing dynamic resize), but will likely need to be
accompanied by a frontend side patch to handle that (which so
far should be a no-op).

>+		break;
>+	default:
>+		break;

Pointless default case.

>+	}
>+
>+out:

I don't think you really need the label (and the goto above) - just
put a return there.

>+	return NOTIFY_DONE;
>+}
>+
> static int netback_remove(struct xenbus_device *dev)
> {
> 	struct backend_info *be = dev_get_drvdata(&dev->dev);
> 
> 	unregister_hotplug_status_watch(be);
>+	unregister_netdevice_notifier(&be->vif_notifier);
> 	if (be->vif) {
> 		kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
> 		xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
>@@ -129,6 +161,10 @@ static int netback_probe(struct xenbus_device *dev,
> 	/* This kicks hotplug scripts, so do it immediately. */
> 	backend_create_xenvif(be);
> 
>+	/* Register Frontend Event Notify */
>+	(be->vif_notifier).notifier_call = netback_netdev_event;

Pointless parentheses.

Jan

>+	register_netdevice_notifier(&be->vif_notifier);
>+
> 	return 0;
> 
> abort_transaction:


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 410018c..ead1a28 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -26,6 +26,7 @@  struct backend_info {
 	struct xenvif *vif;
 	enum xenbus_state frontend_state;
 	struct xenbus_watch hotplug_status_watch;
+	struct notifier_block vif_notifier;
 	u8 have_hotplug_status_watch:1;
 };
 
@@ -34,11 +35,42 @@  static void connect(struct backend_info *);
 static void backend_create_xenvif(struct backend_info *be);
 static void unregister_hotplug_status_watch(struct backend_info *be);
 
+#define nb_to_backend(nb) container_of(nb, struct backend_info, vif_notifier)
+/**
+ * When network condition of vif change, notify the frontend.
+ */
+static int netback_netdev_event(struct notifier_block *this,
+				unsigned long event, void *ptr)
+{
+	struct net_device *event_dev = (struct net_device *)ptr;
+	struct backend_info *be = nb_to_backend(this);
+
+	pr_debug("event_dev: %s, event: %lx\n",
+		 event_dev ? event_dev->name : "None", event);
+
+	if (!be->vif)
+		goto out;
+
+	switch (event) {
+	case NETDEV_NOTIFY_PEERS:
+		/* Notify frontend to Send gratuitous ARP */
+		xenbus_switch_state(be->dev, XenbusStateInitialised);
+		xenbus_switch_state(be->dev, XenbusStateConnected);
+		break;
+	default:
+		break;
+	}
+
+out:
+	return NOTIFY_DONE;
+}
+
 static int netback_remove(struct xenbus_device *dev)
 {
 	struct backend_info *be = dev_get_drvdata(&dev->dev);
 
 	unregister_hotplug_status_watch(be);
+	unregister_netdevice_notifier(&be->vif_notifier);
 	if (be->vif) {
 		kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
 		xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
@@ -129,6 +161,10 @@  static int netback_probe(struct xenbus_device *dev,
 	/* This kicks hotplug scripts, so do it immediately. */
 	backend_create_xenvif(be);
 
+	/* Register Frontend Event Notify */
+	(be->vif_notifier).notifier_call = netback_netdev_event;
+	register_netdevice_notifier(&be->vif_notifier);
+
 	return 0;
 
 abort_transaction: