All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch, rfc] put IP addresses into xenstore
@ 2005-12-21 15:35 Gerd Knorr
  2005-12-21 15:49 ` Keir Fraser
  0 siblings, 1 reply; 4+ messages in thread
From: Gerd Knorr @ 2005-12-21 15:35 UTC (permalink / raw)
  To: Xen devel list

[-- Attachment #1: Type: text/plain, Size: 257 bytes --]

   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


[-- Attachment #2: ip-in-xenstore-2.diff --]
[-- Type: text/x-patch, Size: 5767 bytes --]

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);
 }

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch, rfc] put IP addresses into xenstore
  2005-12-21 15:35 [patch, rfc] put IP addresses into xenstore Gerd Knorr
@ 2005-12-21 15:49 ` Keir Fraser
  2005-12-21 16:40   ` Gerd Knorr
  0 siblings, 1 reply; 4+ messages in thread
From: Keir Fraser @ 2005-12-21 15:49 UTC (permalink / raw)
  To: Gerd Knorr; +Cc: Xen devel list


On 21 Dec 2005, at 15:35, Gerd Knorr wrote:

> $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.

I would expect most setups will have a central authority assigning IP 
addresses to domains, either via DHCP or boot-time IP p'n'p. That would 
seem to be a better place to get domain-to-IP binding info from rather 
than trusting the domU itself. Unfortunately it's also slightly outside 
teh current scope of the dom0 tool stack.

  -- Keir

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch, rfc] put IP addresses into xenstore
  2005-12-21 15:49 ` Keir Fraser
@ 2005-12-21 16:40   ` Gerd Knorr
  2005-12-21 20:37     ` Charles Duffy
  0 siblings, 1 reply; 4+ messages in thread
From: Gerd Knorr @ 2005-12-21 16:40 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Xen devel list

Keir Fraser wrote:
> 
> I would expect most setups will have a central authority assigning IP 
> addresses to domains, either via DHCP or boot-time IP p'n'p. That would 
> seem to be a better place to get domain-to-IP binding info from rather 
> than trusting the domU itself.

How do you do that?  Assuming there is a dhcp server handing out IP 
addresses (pretty common these days I think).  Is there some way to ask 
the dhcp server whenever there is a valid lease for a given mac address? 
  Other suggestions to figure the IP address for a given domain?

> Unfortunately it's also slightly outside 
> teh current scope of the dom0 tool stack.

But unfortunaly there also seems to be no other standard way, thats why 
I've tried to simply place the addresses in xenstore ...

cheers,

   Gerd

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch, rfc] put IP addresses into xenstore
  2005-12-21 16:40   ` Gerd Knorr
@ 2005-12-21 20:37     ` Charles Duffy
  0 siblings, 0 replies; 4+ messages in thread
From: Charles Duffy @ 2005-12-21 20:37 UTC (permalink / raw)
  To: xen-devel

Gerd Knorr wrote:
> How do you do that?  Assuming there is a dhcp server handing out IP 
> addresses (pretty common these days I think).  Is there some way to ask 
> the dhcp server whenever there is a valid lease for a given mac address? 
>  Other suggestions to figure the IP address for a given domain?

It's fairly common practice to keep this information in DNS -- either 
having your DHCP server issue dynamic DNS updates for 
<hostname>.dhcp.<domainname> or <ethernet-address>.dhcp.<domainname> or 
somesuch.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-12-21 20:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-21 15:35 [patch, rfc] put IP addresses into xenstore Gerd Knorr
2005-12-21 15:49 ` Keir Fraser
2005-12-21 16:40   ` Gerd Knorr
2005-12-21 20:37     ` Charles Duffy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.