WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [patch, rfc] put IP addresses into xenstore

To: Xen devel list <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [patch, rfc] put IP addresses into xenstore
From: Gerd Knorr <kraxel@xxxxxxx>
Date: Wed, 21 Dec 2005 16:35:18 +0100
Delivery-date: Wed, 21 Dec 2005 15:38:14 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050715)
  Hi,

$subject says pretty much all, this patch updates netfront and makes it store the network addresses of the interfaces in xenstore, so it's much easier to figure what IP some virtual machine has and (for example) ssh into it.

comments?

  Gerd

diff -r 332bdc354197 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Fri Dec 16 08:45:39 2005
+++ b/drivers/xen/netfront/netfront.c   Wed Dec 21 12:12:02 2005
@@ -45,12 +45,17 @@
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
 #include <linux/ethtool.h>
+#include <linux/ipv6.h>
+
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
 #include <net/route.h>
+#include <net/addrconf.h>
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
+
 #include <xen/evtchn.h>
 #include <xen/xenbus.h>
 #include <xen/interface/io/netif.h>
@@ -83,6 +88,13 @@
 static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
 static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
 
+struct netfront_addr {
+       int               nr;
+       char              addr[64];
+       void              *ifa;
+       struct list_head  next;
+};
+
 struct netfront_info
 {
        struct list_head list;
@@ -133,6 +145,9 @@
        int tx_ring_ref;
        int rx_ring_ref;
        u8 mac[ETH_ALEN];
+
+       struct list_head addrs;
+       int              addr_nr;
 };
 
 /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
@@ -224,6 +239,7 @@
 
        info = netdev_priv(netdev);
        dev->data = info;
+       INIT_LIST_HEAD(&info->addrs);
 
        err = talk_to_backend(dev, info);
        if (err) {
@@ -442,6 +458,55 @@
        return dev_queue_xmit(skb);
 }
 
+static int xenbus_address(struct net_device *netdev,
+                         struct netfront_addr *addr, int add)
+{
+       struct netfront_info *info = netdev_priv(netdev);
+       struct xenbus_device *dev = info->xbdev;
+       struct xenbus_transaction *xbt;
+       char *message, path[16];
+       int err = 0;
+
+       printk(KERN_DEBUG "%s: %s: %s #%d %s\n", __FUNCTION__, netdev->name,
+              add ? "add" : "del", addr->nr, addr->addr);
+ again:
+       xbt = xenbus_transaction_start();
+       if (IS_ERR(xbt)) {
+               xenbus_dev_fatal(dev, err, "starting transaction");
+               goto err;
+       }
+
+       snprintf(path, sizeof(path), "addrs/%d", addr->nr);
+       if (add) {
+               err = xenbus_printf(xbt, dev->nodename, path, "%s", addr->addr);
+               if (err) {
+                       message = "adding address";
+                       goto abort_transaction;
+               }
+       } else {
+               err = xenbus_rm(xbt, dev->nodename, path);
+               if (err) {
+                       message = "deleting address";
+                       goto abort_transaction;
+               }
+       }
+
+       err = xenbus_transaction_end(xbt, 0);
+       if (err) {
+               if (err == -EAGAIN)
+                       goto again;
+               xenbus_dev_fatal(dev, err, "completing transaction");
+               goto err;
+       }
+
+       return 0;
+
+ abort_transaction:
+       xenbus_transaction_end(xbt, 1);
+       xenbus_dev_fatal(dev, err, "%s", message);
+ err:
+       return -1;
+}
 
 static int network_open(struct net_device *dev)
 {
@@ -1147,19 +1212,87 @@
  * We use this notifier to send out a fake ARP reply to reset switches and
  * router ARP caches when an IP interface is brought up on a VIF.
  */
+
+static struct netfront_addr* get_netfront_addr(struct net_device *netdev, void 
*ifa)
+{
+       struct netfront_info *info = netdev_priv(netdev);
+       struct netfront_addr *addr;
+
+       list_for_each_entry(addr, &info->addrs, next)
+               if (addr->ifa == ifa)
+                       return addr;
+
+       addr = kzalloc(sizeof(*addr), GFP_KERNEL);
+       if (NULL == addr)
+               goto out;
+       addr->nr = info->addr_nr++;
+       addr->ifa = ifa;
+       list_add_tail(&addr->next, &info->addrs);
+ out:
+       return addr;
+}
+
 static int 
 inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
 {
-       struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr; 
+       struct in_ifaddr  *ifa = ptr; 
        struct net_device *dev = ifa->ifa_dev->dev;
-
-       /* UP event and is it one of our devices? */
-       if (event == NETDEV_UP && dev->open == network_open)
-               (void)send_fake_arp(dev);
-        
+       struct netfront_addr *addr;
+
+       /* is it one of our devices? */
+       if (dev->open != network_open)
+               return NOTIFY_DONE;
+
+       addr = get_netfront_addr(dev, ifa);
+       switch (event) {
+       case NETDEV_UP:
+               send_fake_arp(dev);
+               snprintf(addr->addr, sizeof(addr->addr),
+                        "inet %u.%u.%u.%u/%d",
+                        NIPQUAD(ifa->ifa_address), ifa->ifa_prefixlen);
+               xenbus_address(dev, addr, 1);
+               break;
+       case NETDEV_DOWN:
+               xenbus_address(dev, addr, 0);
+               list_del(&addr->next);
+               kfree(addr);
+               break;
+       }
+
        return NOTIFY_DONE;
 }
 
+#ifdef CONFIG_IPV6
+/* FIXME: how deal with ipv6 being a module ??? */
+static int 
+inet6dev_notify(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       struct inet6_ifaddr *ifa = ptr; 
+       struct net_device   *dev = ifa->idev->dev;
+       struct netfront_addr *addr;
+
+       /* is it one of our devices? */
+       if (dev->open != network_open)
+               return NOTIFY_DONE;
+
+       addr = get_netfront_addr(dev, ifa);
+       switch (event) {
+       case NETDEV_UP:
+               snprintf(addr->addr, sizeof(addr->addr),
+                        "inet6 %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x/%d",
+                        NIP6(ifa->addr), ifa->prefix_len);
+               xenbus_address(dev, addr, 1);
+               break;
+       case NETDEV_DOWN:
+               xenbus_address(dev, addr, 0);
+               list_del(&addr->next);
+               kfree(addr);
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+#endif
 
 /* ** Close down ** */
 
@@ -1266,9 +1399,13 @@
 
 static struct notifier_block notifier_inetdev = {
        .notifier_call  = inetdev_notify,
-       .next           = NULL,
-       .priority       = 0
 };
+
+#ifdef CONFIG_IPV6
+static struct notifier_block notifier_inet6dev = {
+       .notifier_call  = inet6dev_notify,
+};
+#endif
 
 static int __init netif_init(void)
 {
@@ -1282,7 +1419,10 @@
 
        IPRINTK("Initialising virtual ethernet driver.\n");
 
-       (void)register_inetaddr_notifier(&notifier_inetdev);
+       register_inetaddr_notifier(&notifier_inetdev);
+#ifdef CONFIG_IPV6
+       register_inet6addr_notifier(&notifier_inet6dev);
+#endif
 
        return xenbus_register_frontend(&netfront);
 }
@@ -1292,6 +1432,9 @@
 static void netif_exit(void)
 {
        unregister_inetaddr_notifier(&notifier_inetdev);
+#ifdef CONFIG_IPV6
+       unregister_inet6addr_notifier(&notifier_inet6dev);
+#endif
 
        return xenbus_unregister_driver(&netfront);
 }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>