All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:24   ` Joe Perches
  2012-07-14 23:23       ` KY Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                     ` (14 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Joe Perches @ 2012-07-14 20:24 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw

On Sat, 2012-07-14 at 13:34 -0700, K. Y. Srinivasan wrote:
> Format GUIDS as per MSFT standard. This makes interacting with MSFT
> tool stack easier.
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/hv/vmbus_drv.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index a220e57..1f7e54a 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
>  
>  	if (!strcmp(dev_attr->attr.name, "class_id")) {
>  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
>  			       device_info->chn_type.b[3],
>  			       device_info->chn_type.b[2],
>  			       device_info->chn_type.b[1],
> @@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
>  			       device_info->chn_type.b[15]);
>  	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
>  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
>  			       device_info->chn_instance.b[3],
>  			       device_info->chn_instance.b[2],
>  			       device_info->chn_instance.b[1],

	ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);



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

* [PATCH 00/15] drivers: hv: kvp
@ 2012-07-14 20:32 K. Y. Srinivasan
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
  0 siblings, 1 reply; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:32 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

This patchset expands the KVP (Key Value Pair) functionality to
implement the mechanism to GET/SET IP addresses in the guest. This
functionality is used in Windows Server 2012 to implement VM
replication functionality. The way IP configuration information
is managed is distro specific. Based on the feedback I have gotten
from Olaf, Greg, Steve, Ben and Mairus, I have chosen to seperate
distro specific code from this patch-set. Most of the GET operation
can be implemented in a way that is completely distro independent and
I have implemented that as such and is included in this patch-set.
Some of the attributes that can only be fetched in a distro
dependent way as well the mechanism for configuring an interface
(the SET operation) that is cledarly distro specific is to be
implemented via external scripts that will be invoked via the KVP
code. We define here the interface to these scripts.

K. Y. Srinivasan (15):
  Drivers: hv: Format GUIDS as per MSFT standards
  Drivers: hv: Add KVP definitions for IP address injection
  Drivers: hv: kvp: Cleanup error handling in KVP
  Drivers: hv: kvp: Support the new IP injection messages
  Tools: hv: Prepare to expand  kvp_get_ip_address() functionality
  Tools: hv: Further refactor kvp_get_ip_address()
  Tools: hv: Gather address family information
  Tools: hv: Gather subnet information
  Tools: hv: Represent the ipv6 mask using CIDR notation
  Tools: hv: Gather ipv[4,6] gateway information
  Tools: hv: Gather DNS information
  Tools: hv: Gather DHCP information
  Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO
  Tools: hv: Rename the function kvp_get_ip_address()
  Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO

 drivers/hv/hv_kvp.c      |  172 +++++++++--
 drivers/hv/hv_util.c     |    4 +-
 drivers/hv/vmbus_drv.c   |    4 +-
 include/linux/hyperv.h   |   45 +++-
 tools/hv/hv_kvp_daemon.c |  804 +++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 914 insertions(+), 115 deletions(-)

-- 
1.7.4.1


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

* [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-14 20:32 [PATCH 00/15] drivers: hv: kvp K. Y. Srinivasan
@ 2012-07-14 20:34 ` K. Y. Srinivasan
  2012-07-14 20:24   ` Joe Perches
                     ` (15 more replies)
  0 siblings, 16 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Format GUIDS as per MSFT standard. This makes interacting with MSFT
tool stack easier.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/vmbus_drv.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index a220e57..1f7e54a 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
 
 	if (!strcmp(dev_attr->attr.name, "class_id")) {
 		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
 			       device_info->chn_type.b[3],
 			       device_info->chn_type.b[2],
 			       device_info->chn_type.b[1],
@@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
 			       device_info->chn_type.b[15]);
 	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
 		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
 			       device_info->chn_instance.b[3],
 			       device_info->chn_instance.b[2],
 			       device_info->chn_instance.b[1],
-- 
1.7.4.1


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

* [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Add the necessary definitions for supporting the IP injection functionality.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_util.c     |    4 ++--
 include/linux/hyperv.h   |   30 ++++++++++++++++++++++++++++++
 tools/hv/hv_kvp_daemon.c |    2 +-
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index d3ac6a4..a0667de 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev,
 		(struct hv_util_service *)dev_id->driver_data;
 	int ret;
 
-	srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	srv->recv_buffer = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
 	if (!srv->recv_buffer)
 		return -ENOMEM;
 	if (srv->util_init) {
@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev,
 		}
 	}
 
-	ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
+	ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
 			srv->util_cb, dev->channel);
 	if (ret)
 		goto error;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 68ed7f7..38b561a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -127,6 +127,8 @@ enum hv_kvp_exchg_op {
 	KVP_OP_SET,
 	KVP_OP_DELETE,
 	KVP_OP_ENUMERATE,
+	KVP_OP_GET_IP_INFO,
+	KVP_OP_SET_IP_INFO,
 	KVP_OP_REGISTER,
 	KVP_OP_COUNT /* Number of operations, must be last. */
 };
@@ -140,6 +142,26 @@ enum hv_kvp_exchg_pool {
 	KVP_POOL_COUNT /* Number of pools, must be last. */
 };
 
+#define ADDR_FAMILY_NONE	0x00
+#define ADDR_FAMILY_IPV4	0x01
+#define ADDR_FAMILY_IPV6	0x02
+
+#define MAX_ADAPTER_ID_SIZE	128
+#define MAX_IP_ADDR_SIZE	1024
+#define MAX_GATEWAY_SIZE	512
+
+
+struct hv_kvp_ipaddr_value {
+	__u16	adapter_id[MAX_ADAPTER_ID_SIZE];
+	__u8	addr_family;
+	__u8	dhcp_enabled;
+	__u16	ip_addr[MAX_IP_ADDR_SIZE];
+	__u16	sub_net[MAX_IP_ADDR_SIZE];
+	__u16	gate_way[MAX_GATEWAY_SIZE];
+	__u16	dns_addr[MAX_IP_ADDR_SIZE];
+} __attribute__((packed));
+
+
 struct hv_kvp_hdr {
 	__u8 operation;
 	__u8 pool;
@@ -187,10 +209,17 @@ struct hv_kvp_msg {
 		struct hv_kvp_msg_set		kvp_set;
 		struct hv_kvp_msg_delete	kvp_delete;
 		struct hv_kvp_msg_enumerate	kvp_enum_data;
+		struct hv_kvp_ipaddr_value      kvp_ip_val;
 		struct hv_kvp_register		kvp_register;
 	} body;
 } __attribute__((packed));
 
+struct hv_kvp_ip_msg {
+	__u8 operation;
+	__u8 pool;
+	struct hv_kvp_ipaddr_value      kvp_ip_val;
+} __attribute__((packed));
+
 #ifdef __KERNEL__
 #include <linux/scatterlist.h>
 #include <linux/list.h>
@@ -982,6 +1011,7 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
 #define HV_S_CONT			0x80070103
 #define HV_ERROR_NOT_SUPPORTED		0x80070032
 #define HV_ERROR_MACHINE_LOCKED		0x800704F7
+#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
 
 /*
  * While we want to handle util services as regular devices,
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index d9834b3..8fbcf7b 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -69,7 +69,7 @@ enum key_index {
 };
 
 static char kvp_send_buffer[4096];
-static char kvp_recv_buffer[4096];
+static char kvp_recv_buffer[4096 * 2];
 static struct sockaddr_nl addr;
 
 static char *os_name = "";
-- 
1.7.4.1


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

* [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Add the necessary definitions for supporting the IP injection functionality.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_util.c     |    4 ++--
 include/linux/hyperv.h   |   30 ++++++++++++++++++++++++++++++
 tools/hv/hv_kvp_daemon.c |    2 +-
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index d3ac6a4..a0667de 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev,
 		(struct hv_util_service *)dev_id->driver_data;
 	int ret;
 
-	srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	srv->recv_buffer = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
 	if (!srv->recv_buffer)
 		return -ENOMEM;
 	if (srv->util_init) {
@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev,
 		}
 	}
 
-	ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
+	ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
 			srv->util_cb, dev->channel);
 	if (ret)
 		goto error;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 68ed7f7..38b561a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -127,6 +127,8 @@ enum hv_kvp_exchg_op {
 	KVP_OP_SET,
 	KVP_OP_DELETE,
 	KVP_OP_ENUMERATE,
+	KVP_OP_GET_IP_INFO,
+	KVP_OP_SET_IP_INFO,
 	KVP_OP_REGISTER,
 	KVP_OP_COUNT /* Number of operations, must be last. */
 };
@@ -140,6 +142,26 @@ enum hv_kvp_exchg_pool {
 	KVP_POOL_COUNT /* Number of pools, must be last. */
 };
 
+#define ADDR_FAMILY_NONE	0x00
+#define ADDR_FAMILY_IPV4	0x01
+#define ADDR_FAMILY_IPV6	0x02
+
+#define MAX_ADAPTER_ID_SIZE	128
+#define MAX_IP_ADDR_SIZE	1024
+#define MAX_GATEWAY_SIZE	512
+
+
+struct hv_kvp_ipaddr_value {
+	__u16	adapter_id[MAX_ADAPTER_ID_SIZE];
+	__u8	addr_family;
+	__u8	dhcp_enabled;
+	__u16	ip_addr[MAX_IP_ADDR_SIZE];
+	__u16	sub_net[MAX_IP_ADDR_SIZE];
+	__u16	gate_way[MAX_GATEWAY_SIZE];
+	__u16	dns_addr[MAX_IP_ADDR_SIZE];
+} __attribute__((packed));
+
+
 struct hv_kvp_hdr {
 	__u8 operation;
 	__u8 pool;
@@ -187,10 +209,17 @@ struct hv_kvp_msg {
 		struct hv_kvp_msg_set		kvp_set;
 		struct hv_kvp_msg_delete	kvp_delete;
 		struct hv_kvp_msg_enumerate	kvp_enum_data;
+		struct hv_kvp_ipaddr_value      kvp_ip_val;
 		struct hv_kvp_register		kvp_register;
 	} body;
 } __attribute__((packed));
 
+struct hv_kvp_ip_msg {
+	__u8 operation;
+	__u8 pool;
+	struct hv_kvp_ipaddr_value      kvp_ip_val;
+} __attribute__((packed));
+
 #ifdef __KERNEL__
 #include <linux/scatterlist.h>
 #include <linux/list.h>
@@ -982,6 +1011,7 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
 #define HV_S_CONT			0x80070103
 #define HV_ERROR_NOT_SUPPORTED		0x80070032
 #define HV_ERROR_MACHINE_LOCKED		0x800704F7
+#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
 
 /*
  * While we want to handle util services as regular devices,
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index d9834b3..8fbcf7b 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -69,7 +69,7 @@ enum key_index {
 };
 
 static char kvp_send_buffer[4096];
-static char kvp_recv_buffer[4096];
+static char kvp_recv_buffer[4096 * 2];
 static struct sockaddr_nl addr;
 
 static char *os_name = "";
-- 
1.7.4.1

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

* [PATCH 03/15] Drivers: hv: kvp: Cleanup error handling in KVP
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

In preparation to implementing IP injection, cleanup the way we propagate
and handle errors both in the driver as well as in the user level daemon.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_kvp.c      |   43 +++++++++++++++++----------------
 include/linux/hyperv.h   |   17 ++++++++----
 tools/hv/hv_kvp_daemon.c |   59 +++++++++++++++++++++++----------------------
 3 files changed, 63 insertions(+), 56 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 0012eed..6e6f0c2 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -50,7 +50,6 @@ static struct {
 
 static void kvp_send_key(struct work_struct *dummy);
 
-#define TIMEOUT_FIRED 1
 
 static void kvp_respond_to_host(char *key, char *value, int error);
 static void kvp_work_func(struct work_struct *dummy);
@@ -97,7 +96,7 @@ kvp_work_func(struct work_struct *dummy)
 	 * If the timer fires, the user-mode component has not responded;
 	 * process the pending transaction.
 	 */
-	kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
+	kvp_respond_to_host("Unknown key", "Guest timed out", HV_E_FAIL);
 }
 
 /*
@@ -109,27 +108,31 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
 	struct hv_kvp_msg *message;
 	struct hv_kvp_msg_enumerate *data;
+	int	error;
 
 	message = (struct hv_kvp_msg *)msg->data;
-	switch (message->kvp_hdr.operation) {
-	case KVP_OP_REGISTER:
+
+	if (message->kvp_hdr.operation == KVP_OP_REGISTER) {
 		pr_info("KVP: user-mode registering done.\n");
 		kvp_register();
 		kvp_transaction.active = false;
-		hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
-		break;
-
-	default:
-		data = &message->body.kvp_enum_data;
-		/*
-		 * Complete the transaction by forwarding the key value
-		 * to the host. But first, cancel the timeout.
-		 */
-		if (cancel_delayed_work_sync(&kvp_work))
-			kvp_respond_to_host(data->data.key,
-					 data->data.value,
-					!strlen(data->data.key));
+		if (kvp_transaction.kvp_context)
+			hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
+		return;
 	}
+
+	/*
+	 * We use the message header information from
+	 * the user level daemon to transmit errors.
+	 */
+	error = *((int *)(&message->kvp_hdr.operation));
+	data = &message->body.kvp_enum_data;
+	/*
+	 * Complete the transaction by forwarding the key value
+	 * to the host. But first, cancel the timeout.
+	 */
+	if (cancel_delayed_work_sync(&kvp_work))
+		kvp_respond_to_host(data->data.key, data->data.value, error);
 }
 
 static void
@@ -287,6 +290,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 		 */
 		return;
 
+	icmsghdrp->status = error;
 
 	/*
 	 * If the error parameter is set, terminate the host's enumeration
@@ -294,15 +298,12 @@ kvp_respond_to_host(char *key, char *value, int error)
 	 */
 	if (error) {
 		/*
-		 * Something failed or the we have timedout;
+		 * Something failed or  we have timedout;
 		 * terminate the current  host-side iteration.
 		 */
-		icmsghdrp->status = HV_S_CONT;
 		goto response_done;
 	}
 
-	icmsghdrp->status = HV_S_OK;
-
 	kvp_msg = (struct hv_kvp_msg *)
 			&recv_buffer[sizeof(struct vmbuspipe_hdr) +
 			sizeof(struct icmsg_hdr)];
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 38b561a..dfa9bb2 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -142,6 +142,17 @@ enum hv_kvp_exchg_pool {
 	KVP_POOL_COUNT /* Number of pools, must be last. */
 };
 
+/*
+ * Some Hyper-V status codes.
+ */
+
+#define HV_S_OK				0x00000000
+#define HV_E_FAIL			0x80004005
+#define HV_S_CONT			0x80070103
+#define HV_ERROR_NOT_SUPPORTED		0x80070032
+#define HV_ERROR_MACHINE_LOCKED		0x800704F7
+#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
+
 #define ADDR_FAMILY_NONE	0x00
 #define ADDR_FAMILY_IPV4	0x01
 #define ADDR_FAMILY_IPV6	0x02
@@ -1006,12 +1017,6 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
 #define ICMSGHDRFLAG_REQUEST		2
 #define ICMSGHDRFLAG_RESPONSE		4
 
-#define HV_S_OK				0x00000000
-#define HV_E_FAIL			0x80004005
-#define HV_S_CONT			0x80070103
-#define HV_ERROR_NOT_SUPPORTED		0x80070032
-#define HV_ERROR_MACHINE_LOCKED		0x800704F7
-#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
 
 /*
  * While we want to handle util services as regular devices,
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 8fbcf7b..ffe444b 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -394,7 +394,7 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
 	return 1;
 }
 
-static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
+static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
 				__u8 *value, int value_size)
 {
 	struct kvp_record *record;
@@ -406,16 +406,12 @@ static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
 	record = kvp_file_info[pool].records;
 
 	if (index >= kvp_file_info[pool].num_records) {
-		/*
-		 * This is an invalid index; terminate enumeration;
-		 * - a NULL value will do the trick.
-		 */
-		strcpy(value, "");
-		return;
+		return 1;
 	}
 
 	memcpy(key, record[index].key, key_size);
 	memcpy(value, record[index].value, value_size);
+	return 0;
 }
 
 
@@ -646,6 +642,8 @@ int main(void)
 	char	*p;
 	char	*key_value;
 	char	*key_name;
+	int	op;
+	int	pool;
 
 	daemon(1, 0);
 	openlog("KVP", 0, LOG_USER);
@@ -721,7 +719,16 @@ int main(void)
 		incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
 		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
 
-		switch (hv_msg->kvp_hdr.operation) {
+		/*
+		 * We will use the KVP header information to pass back
+		 * the error from this daemon. So, first copy the state
+		 * and set the error code to success.
+		 */
+		op = hv_msg->kvp_hdr.operation;
+		pool = hv_msg->kvp_hdr.pool;
+		*((int *)(&hv_msg->kvp_hdr.operation)) = HV_S_OK;
+
+		switch (op) {
 		case KVP_OP_REGISTER:
 			/*
 			 * Driver is registering with us; stash away the version
@@ -738,36 +745,32 @@ int main(void)
 			}
 			continue;
 
-		/*
-		 * The current protocol with the kernel component uses a
-		 * NULL key name to pass an error condition.
-		 * For the SET, GET and DELETE operations,
-		 * use the existing protocol to pass back error.
-		 */
-
 		case KVP_OP_SET:
-			if (kvp_key_add_or_modify(hv_msg->kvp_hdr.pool,
+			if (kvp_key_add_or_modify(pool,
 					hv_msg->body.kvp_set.data.key,
 					hv_msg->body.kvp_set.data.key_size,
 					hv_msg->body.kvp_set.data.value,
 					hv_msg->body.kvp_set.data.value_size))
-				strcpy(hv_msg->body.kvp_set.data.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		case KVP_OP_GET:
-			if (kvp_get_value(hv_msg->kvp_hdr.pool,
+			if (kvp_get_value(pool,
 					hv_msg->body.kvp_set.data.key,
 					hv_msg->body.kvp_set.data.key_size,
 					hv_msg->body.kvp_set.data.value,
 					hv_msg->body.kvp_set.data.value_size))
-				strcpy(hv_msg->body.kvp_set.data.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		case KVP_OP_DELETE:
-			if (kvp_key_delete(hv_msg->kvp_hdr.pool,
+			if (kvp_key_delete(pool,
 					hv_msg->body.kvp_delete.key,
 					hv_msg->body.kvp_delete.key_size))
-				strcpy(hv_msg->body.kvp_delete.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		default:
@@ -782,13 +785,15 @@ int main(void)
 		 * both the key and the value; if not read from the
 		 * appropriate pool.
 		 */
-		if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) {
-			kvp_pool_enumerate(hv_msg->kvp_hdr.pool,
+		if (pool != KVP_POOL_AUTO) {
+			if (kvp_pool_enumerate(pool,
 					hv_msg->body.kvp_enum_data.index,
 					hv_msg->body.kvp_enum_data.data.key,
 					HV_KVP_EXCHANGE_MAX_KEY_SIZE,
 					hv_msg->body.kvp_enum_data.data.value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+					HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			goto kvp_done;
 		}
 
@@ -841,11 +846,7 @@ int main(void)
 			strcpy(key_name, "ProcessorArchitecture");
 			break;
 		default:
-			strcpy(key_value, "Unknown Key");
-			/*
-			 * We use a null key name to terminate enumeration.
-			 */
-			strcpy(key_name, "");
+			*((int *)(&hv_msg->kvp_hdr.operation)) = HV_S_CONT;
 			break;
 		}
 		/*
-- 
1.7.4.1


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

* [PATCH 03/15] Drivers: hv: kvp: Cleanup error handling in KVP
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

In preparation to implementing IP injection, cleanup the way we propagate
and handle errors both in the driver as well as in the user level daemon.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_kvp.c      |   43 +++++++++++++++++----------------
 include/linux/hyperv.h   |   17 ++++++++----
 tools/hv/hv_kvp_daemon.c |   59 +++++++++++++++++++++++----------------------
 3 files changed, 63 insertions(+), 56 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 0012eed..6e6f0c2 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -50,7 +50,6 @@ static struct {
 
 static void kvp_send_key(struct work_struct *dummy);
 
-#define TIMEOUT_FIRED 1
 
 static void kvp_respond_to_host(char *key, char *value, int error);
 static void kvp_work_func(struct work_struct *dummy);
@@ -97,7 +96,7 @@ kvp_work_func(struct work_struct *dummy)
 	 * If the timer fires, the user-mode component has not responded;
 	 * process the pending transaction.
 	 */
-	kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
+	kvp_respond_to_host("Unknown key", "Guest timed out", HV_E_FAIL);
 }
 
 /*
@@ -109,27 +108,31 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
 	struct hv_kvp_msg *message;
 	struct hv_kvp_msg_enumerate *data;
+	int	error;
 
 	message = (struct hv_kvp_msg *)msg->data;
-	switch (message->kvp_hdr.operation) {
-	case KVP_OP_REGISTER:
+
+	if (message->kvp_hdr.operation == KVP_OP_REGISTER) {
 		pr_info("KVP: user-mode registering done.\n");
 		kvp_register();
 		kvp_transaction.active = false;
-		hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
-		break;
-
-	default:
-		data = &message->body.kvp_enum_data;
-		/*
-		 * Complete the transaction by forwarding the key value
-		 * to the host. But first, cancel the timeout.
-		 */
-		if (cancel_delayed_work_sync(&kvp_work))
-			kvp_respond_to_host(data->data.key,
-					 data->data.value,
-					!strlen(data->data.key));
+		if (kvp_transaction.kvp_context)
+			hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
+		return;
 	}
+
+	/*
+	 * We use the message header information from
+	 * the user level daemon to transmit errors.
+	 */
+	error = *((int *)(&message->kvp_hdr.operation));
+	data = &message->body.kvp_enum_data;
+	/*
+	 * Complete the transaction by forwarding the key value
+	 * to the host. But first, cancel the timeout.
+	 */
+	if (cancel_delayed_work_sync(&kvp_work))
+		kvp_respond_to_host(data->data.key, data->data.value, error);
 }
 
 static void
@@ -287,6 +290,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 		 */
 		return;
 
+	icmsghdrp->status = error;
 
 	/*
 	 * If the error parameter is set, terminate the host's enumeration
@@ -294,15 +298,12 @@ kvp_respond_to_host(char *key, char *value, int error)
 	 */
 	if (error) {
 		/*
-		 * Something failed or the we have timedout;
+		 * Something failed or  we have timedout;
 		 * terminate the current  host-side iteration.
 		 */
-		icmsghdrp->status = HV_S_CONT;
 		goto response_done;
 	}
 
-	icmsghdrp->status = HV_S_OK;
-
 	kvp_msg = (struct hv_kvp_msg *)
 			&recv_buffer[sizeof(struct vmbuspipe_hdr) +
 			sizeof(struct icmsg_hdr)];
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 38b561a..dfa9bb2 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -142,6 +142,17 @@ enum hv_kvp_exchg_pool {
 	KVP_POOL_COUNT /* Number of pools, must be last. */
 };
 
+/*
+ * Some Hyper-V status codes.
+ */
+
+#define HV_S_OK				0x00000000
+#define HV_E_FAIL			0x80004005
+#define HV_S_CONT			0x80070103
+#define HV_ERROR_NOT_SUPPORTED		0x80070032
+#define HV_ERROR_MACHINE_LOCKED		0x800704F7
+#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
+
 #define ADDR_FAMILY_NONE	0x00
 #define ADDR_FAMILY_IPV4	0x01
 #define ADDR_FAMILY_IPV6	0x02
@@ -1006,12 +1017,6 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
 #define ICMSGHDRFLAG_REQUEST		2
 #define ICMSGHDRFLAG_RESPONSE		4
 
-#define HV_S_OK				0x00000000
-#define HV_E_FAIL			0x80004005
-#define HV_S_CONT			0x80070103
-#define HV_ERROR_NOT_SUPPORTED		0x80070032
-#define HV_ERROR_MACHINE_LOCKED		0x800704F7
-#define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
 
 /*
  * While we want to handle util services as regular devices,
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 8fbcf7b..ffe444b 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -394,7 +394,7 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
 	return 1;
 }
 
-static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
+static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
 				__u8 *value, int value_size)
 {
 	struct kvp_record *record;
@@ -406,16 +406,12 @@ static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
 	record = kvp_file_info[pool].records;
 
 	if (index >= kvp_file_info[pool].num_records) {
-		/*
-		 * This is an invalid index; terminate enumeration;
-		 * - a NULL value will do the trick.
-		 */
-		strcpy(value, "");
-		return;
+		return 1;
 	}
 
 	memcpy(key, record[index].key, key_size);
 	memcpy(value, record[index].value, value_size);
+	return 0;
 }
 
 
@@ -646,6 +642,8 @@ int main(void)
 	char	*p;
 	char	*key_value;
 	char	*key_name;
+	int	op;
+	int	pool;
 
 	daemon(1, 0);
 	openlog("KVP", 0, LOG_USER);
@@ -721,7 +719,16 @@ int main(void)
 		incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
 		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
 
-		switch (hv_msg->kvp_hdr.operation) {
+		/*
+		 * We will use the KVP header information to pass back
+		 * the error from this daemon. So, first copy the state
+		 * and set the error code to success.
+		 */
+		op = hv_msg->kvp_hdr.operation;
+		pool = hv_msg->kvp_hdr.pool;
+		*((int *)(&hv_msg->kvp_hdr.operation)) = HV_S_OK;
+
+		switch (op) {
 		case KVP_OP_REGISTER:
 			/*
 			 * Driver is registering with us; stash away the version
@@ -738,36 +745,32 @@ int main(void)
 			}
 			continue;
 
-		/*
-		 * The current protocol with the kernel component uses a
-		 * NULL key name to pass an error condition.
-		 * For the SET, GET and DELETE operations,
-		 * use the existing protocol to pass back error.
-		 */
-
 		case KVP_OP_SET:
-			if (kvp_key_add_or_modify(hv_msg->kvp_hdr.pool,
+			if (kvp_key_add_or_modify(pool,
 					hv_msg->body.kvp_set.data.key,
 					hv_msg->body.kvp_set.data.key_size,
 					hv_msg->body.kvp_set.data.value,
 					hv_msg->body.kvp_set.data.value_size))
-				strcpy(hv_msg->body.kvp_set.data.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		case KVP_OP_GET:
-			if (kvp_get_value(hv_msg->kvp_hdr.pool,
+			if (kvp_get_value(pool,
 					hv_msg->body.kvp_set.data.key,
 					hv_msg->body.kvp_set.data.key_size,
 					hv_msg->body.kvp_set.data.value,
 					hv_msg->body.kvp_set.data.value_size))
-				strcpy(hv_msg->body.kvp_set.data.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		case KVP_OP_DELETE:
-			if (kvp_key_delete(hv_msg->kvp_hdr.pool,
+			if (kvp_key_delete(pool,
 					hv_msg->body.kvp_delete.key,
 					hv_msg->body.kvp_delete.key_size))
-				strcpy(hv_msg->body.kvp_delete.key, "");
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			break;
 
 		default:
@@ -782,13 +785,15 @@ int main(void)
 		 * both the key and the value; if not read from the
 		 * appropriate pool.
 		 */
-		if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) {
-			kvp_pool_enumerate(hv_msg->kvp_hdr.pool,
+		if (pool != KVP_POOL_AUTO) {
+			if (kvp_pool_enumerate(pool,
 					hv_msg->body.kvp_enum_data.index,
 					hv_msg->body.kvp_enum_data.data.key,
 					HV_KVP_EXCHANGE_MAX_KEY_SIZE,
 					hv_msg->body.kvp_enum_data.data.value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+					HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+								HV_S_CONT;
 			goto kvp_done;
 		}
 
@@ -841,11 +846,7 @@ int main(void)
 			strcpy(key_name, "ProcessorArchitecture");
 			break;
 		default:
-			strcpy(key_value, "Unknown Key");
-			/*
-			 * We use a null key name to terminate enumeration.
-			 */
-			strcpy(key_name, "");
+			*((int *)(&hv_msg->kvp_hdr.operation)) = HV_S_CONT;
 			break;
 		}
 		/*
-- 
1.7.4.1

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

* [PATCH 04/15] Drivers: hv: kvp: Support the new IP injection messages
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Implement support for the new IP injection messages in the driver code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_kvp.c |  141 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 133 insertions(+), 8 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 6e6f0c2..15c641c 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -51,7 +51,7 @@ static struct {
 static void kvp_send_key(struct work_struct *dummy);
 
 
-static void kvp_respond_to_host(char *key, char *value, int error);
+static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
 static void kvp_work_func(struct work_struct *dummy);
 static void kvp_register(void);
 
@@ -96,7 +96,7 @@ kvp_work_func(struct work_struct *dummy)
 	 * If the timer fires, the user-mode component has not responded;
 	 * process the pending transaction.
 	 */
-	kvp_respond_to_host("Unknown key", "Guest timed out", HV_E_FAIL);
+	kvp_respond_to_host(NULL, HV_E_FAIL);
 }
 
 /*
@@ -107,7 +107,6 @@ static void
 kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
 	struct hv_kvp_msg *message;
-	struct hv_kvp_msg_enumerate *data;
 	int	error;
 
 	message = (struct hv_kvp_msg *)msg->data;
@@ -126,13 +125,119 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 	 * the user level daemon to transmit errors.
 	 */
 	error = *((int *)(&message->kvp_hdr.operation));
-	data = &message->body.kvp_enum_data;
 	/*
 	 * Complete the transaction by forwarding the key value
 	 * to the host. But first, cancel the timeout.
 	 */
 	if (cancel_delayed_work_sync(&kvp_work))
-		kvp_respond_to_host(data->data.key, data->data.value, error);
+		kvp_respond_to_host(message, error);
+}
+
+static int process_ob_ipinfo(void *in_msg, void *out_msg, int op)
+{
+	struct hv_kvp_msg *in = in_msg;
+	struct hv_kvp_ip_msg *out = out_msg;
+	int len;
+
+	switch (op) {
+	case KVP_OP_GET_IP_INFO:
+		/*
+		 * Transform all parameters into utf16 encoding.
+		 */
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr,
+				strlen((char *)in->body.kvp_ip_val.ip_addr),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net,
+				strlen((char *)in->body.kvp_ip_val.sub_net),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way,
+				strlen((char *)in->body.kvp_ip_val.gate_way),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr,
+				strlen((char *)in->body.kvp_ip_val.dns_addr),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id,
+				strlen((char *)in->body.kvp_ip_val.adapter_id),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.adapter_id,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		out->kvp_ip_val.dhcp_enabled =
+			in->body.kvp_ip_val.dhcp_enabled;
+	}
+
+	return 0;
+}
+
+static void process_ib_ipinfo(void *in_msg, void *out_msg, int op)
+{
+	struct hv_kvp_ip_msg *in = in_msg;
+	struct hv_kvp_msg *out = out_msg;
+
+	switch (op) {
+	case KVP_OP_SET_IP_INFO:
+		/*
+		 * Transform all parameters into utf8 encoding.
+		 */
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE);
+
+		out->body.kvp_ip_val.dhcp_enabled =
+			in->kvp_ip_val.dhcp_enabled;
+
+	default:
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
+				MAX_ADAPTER_ID_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.adapter_id,
+				MAX_ADAPTER_ID_SIZE);
+
+		out->body.kvp_ip_val.addr_family =
+		in->kvp_ip_val.addr_family;
+	}
 }
 
 static void
@@ -170,6 +275,12 @@ kvp_send_key(struct work_struct *dummy)
 	 */
 
 	switch (message->kvp_hdr.operation) {
+	case KVP_OP_SET_IP_INFO:
+		process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
+		break;
+	case KVP_OP_GET_IP_INFO:
+		process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
+		break;
 	case KVP_OP_SET:
 		switch (in_msg->body.kvp_set.data.value_type) {
 		case REG_SZ:
@@ -246,17 +357,19 @@ kvp_send_key(struct work_struct *dummy)
  */
 
 static void
-kvp_respond_to_host(char *key, char *value, int error)
+kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error)
 {
 	struct hv_kvp_msg  *kvp_msg;
 	struct hv_kvp_exchg_msg_value  *kvp_data;
 	char	*key_name;
+	char	*value;
 	struct icmsg_hdr *icmsghdrp;
 	int	keylen = 0;
 	int	valuelen = 0;
 	u32	buf_len;
 	struct vmbus_channel *channel;
 	u64	req_id;
+	int ret;
 
 	/*
 	 * If a transaction is not active; log and return.
@@ -309,6 +422,16 @@ kvp_respond_to_host(char *key, char *value, int error)
 			sizeof(struct icmsg_hdr)];
 
 	switch (kvp_transaction.kvp_msg->kvp_hdr.operation) {
+	case KVP_OP_GET_IP_INFO:
+		ret = process_ob_ipinfo(msg_to_host,
+				 (struct hv_kvp_ip_msg *)kvp_msg,
+				 KVP_OP_GET_IP_INFO);
+		if (ret < 0)
+			icmsghdrp->status = HV_E_FAIL;
+
+		goto response_done;
+	case KVP_OP_SET_IP_INFO:
+		goto response_done;
 	case KVP_OP_GET:
 		kvp_data = &kvp_msg->body.kvp_get.data;
 		goto copy_value;
@@ -322,7 +445,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 	}
 
 	kvp_data = &kvp_msg->body.kvp_enum_data.data;
-	key_name = key;
+	key_name = msg_to_host->body.kvp_enum_data.data.key;
 
 	/*
 	 * The windows host expects the key/value pair to be encoded
@@ -336,6 +459,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 	kvp_data->key_size = 2*(keylen + 1); /* utf16 encoding */
 
 copy_value:
+	value = msg_to_host->body.kvp_enum_data.data.value;
 	valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN,
 				(wchar_t *) kvp_data->value,
 				(HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2) - 2);
@@ -388,7 +512,8 @@ void hv_kvp_onchannelcallback(void *context)
 		return;
 	}
 
-	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
+	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
+			 &requestid);
 
 	if (recvlen > 0) {
 		icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
-- 
1.7.4.1


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

* [PATCH 04/15] Drivers: hv: kvp: Support the new IP injection messages
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Implement support for the new IP injection messages in the driver code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/hv/hv_kvp.c |  141 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 133 insertions(+), 8 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 6e6f0c2..15c641c 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -51,7 +51,7 @@ static struct {
 static void kvp_send_key(struct work_struct *dummy);
 
 
-static void kvp_respond_to_host(char *key, char *value, int error);
+static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
 static void kvp_work_func(struct work_struct *dummy);
 static void kvp_register(void);
 
@@ -96,7 +96,7 @@ kvp_work_func(struct work_struct *dummy)
 	 * If the timer fires, the user-mode component has not responded;
 	 * process the pending transaction.
 	 */
-	kvp_respond_to_host("Unknown key", "Guest timed out", HV_E_FAIL);
+	kvp_respond_to_host(NULL, HV_E_FAIL);
 }
 
 /*
@@ -107,7 +107,6 @@ static void
 kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
 	struct hv_kvp_msg *message;
-	struct hv_kvp_msg_enumerate *data;
 	int	error;
 
 	message = (struct hv_kvp_msg *)msg->data;
@@ -126,13 +125,119 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 	 * the user level daemon to transmit errors.
 	 */
 	error = *((int *)(&message->kvp_hdr.operation));
-	data = &message->body.kvp_enum_data;
 	/*
 	 * Complete the transaction by forwarding the key value
 	 * to the host. But first, cancel the timeout.
 	 */
 	if (cancel_delayed_work_sync(&kvp_work))
-		kvp_respond_to_host(data->data.key, data->data.value, error);
+		kvp_respond_to_host(message, error);
+}
+
+static int process_ob_ipinfo(void *in_msg, void *out_msg, int op)
+{
+	struct hv_kvp_msg *in = in_msg;
+	struct hv_kvp_ip_msg *out = out_msg;
+	int len;
+
+	switch (op) {
+	case KVP_OP_GET_IP_INFO:
+		/*
+		 * Transform all parameters into utf16 encoding.
+		 */
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr,
+				strlen((char *)in->body.kvp_ip_val.ip_addr),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net,
+				strlen((char *)in->body.kvp_ip_val.sub_net),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way,
+				strlen((char *)in->body.kvp_ip_val.gate_way),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr,
+				strlen((char *)in->body.kvp_ip_val.dns_addr),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id,
+				strlen((char *)in->body.kvp_ip_val.adapter_id),
+				UTF16_HOST_ENDIAN,
+				(wchar_t *)out->kvp_ip_val.adapter_id,
+				MAX_IP_ADDR_SIZE);
+		if (len < 0)
+			return len;
+
+		out->kvp_ip_val.dhcp_enabled =
+			in->body.kvp_ip_val.dhcp_enabled;
+	}
+
+	return 0;
+}
+
+static void process_ib_ipinfo(void *in_msg, void *out_msg, int op)
+{
+	struct hv_kvp_ip_msg *in = in_msg;
+	struct hv_kvp_msg *out = out_msg;
+
+	switch (op) {
+	case KVP_OP_SET_IP_INFO:
+		/*
+		 * Transform all parameters into utf8 encoding.
+		 */
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.ip_addr,
+				MAX_IP_ADDR_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.sub_net,
+				MAX_IP_ADDR_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.gate_way,
+				MAX_GATEWAY_SIZE);
+
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.dns_addr,
+				MAX_IP_ADDR_SIZE);
+
+		out->body.kvp_ip_val.dhcp_enabled =
+			in->kvp_ip_val.dhcp_enabled;
+
+	default:
+		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
+				MAX_ADAPTER_ID_SIZE,
+				UTF16_LITTLE_ENDIAN,
+				(__u8 *)out->body.kvp_ip_val.adapter_id,
+				MAX_ADAPTER_ID_SIZE);
+
+		out->body.kvp_ip_val.addr_family =
+		in->kvp_ip_val.addr_family;
+	}
 }
 
 static void
@@ -170,6 +275,12 @@ kvp_send_key(struct work_struct *dummy)
 	 */
 
 	switch (message->kvp_hdr.operation) {
+	case KVP_OP_SET_IP_INFO:
+		process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
+		break;
+	case KVP_OP_GET_IP_INFO:
+		process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
+		break;
 	case KVP_OP_SET:
 		switch (in_msg->body.kvp_set.data.value_type) {
 		case REG_SZ:
@@ -246,17 +357,19 @@ kvp_send_key(struct work_struct *dummy)
  */
 
 static void
-kvp_respond_to_host(char *key, char *value, int error)
+kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error)
 {
 	struct hv_kvp_msg  *kvp_msg;
 	struct hv_kvp_exchg_msg_value  *kvp_data;
 	char	*key_name;
+	char	*value;
 	struct icmsg_hdr *icmsghdrp;
 	int	keylen = 0;
 	int	valuelen = 0;
 	u32	buf_len;
 	struct vmbus_channel *channel;
 	u64	req_id;
+	int ret;
 
 	/*
 	 * If a transaction is not active; log and return.
@@ -309,6 +422,16 @@ kvp_respond_to_host(char *key, char *value, int error)
 			sizeof(struct icmsg_hdr)];
 
 	switch (kvp_transaction.kvp_msg->kvp_hdr.operation) {
+	case KVP_OP_GET_IP_INFO:
+		ret = process_ob_ipinfo(msg_to_host,
+				 (struct hv_kvp_ip_msg *)kvp_msg,
+				 KVP_OP_GET_IP_INFO);
+		if (ret < 0)
+			icmsghdrp->status = HV_E_FAIL;
+
+		goto response_done;
+	case KVP_OP_SET_IP_INFO:
+		goto response_done;
 	case KVP_OP_GET:
 		kvp_data = &kvp_msg->body.kvp_get.data;
 		goto copy_value;
@@ -322,7 +445,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 	}
 
 	kvp_data = &kvp_msg->body.kvp_enum_data.data;
-	key_name = key;
+	key_name = msg_to_host->body.kvp_enum_data.data.key;
 
 	/*
 	 * The windows host expects the key/value pair to be encoded
@@ -336,6 +459,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 	kvp_data->key_size = 2*(keylen + 1); /* utf16 encoding */
 
 copy_value:
+	value = msg_to_host->body.kvp_enum_data.data.value;
 	valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN,
 				(wchar_t *) kvp_data->value,
 				(HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2) - 2);
@@ -388,7 +512,8 @@ void hv_kvp_onchannelcallback(void *context)
 		return;
 	}
 
-	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
+	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
+			 &requestid);
 
 	if (recvlen > 0) {
 		icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
-- 
1.7.4.1

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

* [PATCH 05/15] Tools: hv: Prepare to expand  kvp_get_ip_address() functionality
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

kvp_get_ip_address() implemented the functionality to retrieve IP address info.
Make this function more generic so that we could retrieve additional
per-interface information.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |  129 ++++++++++++++++++++++++++++++----------------
 1 files changed, 84 insertions(+), 45 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index ffe444b..3128e77 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -491,7 +491,8 @@ done:
 }
 
 static int
-kvp_get_ip_address(int family, char *buffer, int length)
+kvp_get_ip_address(int family, char *if_name, int op,
+		 void  *out_buffer, int length)
 {
 	struct ifaddrs *ifap;
 	struct ifaddrs *curp;
@@ -501,10 +502,19 @@ kvp_get_ip_address(int family, char *buffer, int length)
 	const char *str;
 	char tmp[50];
 	int error = 0;
-
+	char *buffer;
+	struct hv_kvp_ipaddr_value *ip_buffer;
+
+	if (op == KVP_OP_ENUMERATE) {
+		buffer = out_buffer;
+	} else {
+		ip_buffer = out_buffer;
+		buffer = (char *)ip_buffer->ip_addr;
+		ip_buffer->addr_family = 0;
+	}
 	/*
 	 * On entry into this function, the buffer is capable of holding the
-	 * maximum key value (2048 bytes).
+	 * maximum key value.
 	 */
 
 	if (getifaddrs(&ifap)) {
@@ -514,58 +524,87 @@ kvp_get_ip_address(int family, char *buffer, int length)
 
 	curp = ifap;
 	while (curp != NULL) {
-		if ((curp->ifa_addr != NULL) &&
-		   (curp->ifa_addr->sa_family == family)) {
-			if (family == AF_INET) {
-				struct sockaddr_in *addr =
-				(struct sockaddr_in *) curp->ifa_addr;
-
-				str = inet_ntop(family, &addr->sin_addr,
-						tmp, 50);
-				if (str == NULL) {
-					strcpy(buffer, "inet_ntop failed\n");
-					error = 1;
-					goto getaddr_done;
-				}
-				if (offset == 0)
-					strcpy(buffer, tmp);
-				else
-					strcat(buffer, tmp);
-				strcat(buffer, ";");
+		if (curp->ifa_addr == NULL) {
+			curp = curp->ifa_next;
+			continue;
+		}
 
-				offset += strlen(str) + 1;
-				if ((length - offset) < (ipv4_len + 1))
-					goto getaddr_done;
+		if ((if_name != NULL) &&
+			(strncmp(curp->ifa_name, if_name, strlen(if_name)))) {
+			/*
+			 * We want info about a specific interface;
+			 * just continue.
+			 */
+			curp = curp->ifa_next;
+			continue;
+		}
 
-			} else {
+		/*
+		 * We only support two address families: AF_INET and AF_INET6.
+		 * If a family value of 0 is specified, we collect both
+		 * supported address families; if not we gather info on
+		 * the specified address family.
+		 */
+		if ((family != 0) && (curp->ifa_addr->sa_family != family)) {
+			curp = curp->ifa_next;
+			continue;
+		}
+		if ((curp->ifa_addr->sa_family != AF_INET) &&
+			(curp->ifa_addr->sa_family != AF_INET6)) {
+			curp = curp->ifa_next;
+			continue;
+		}
+
+		if ((curp->ifa_addr->sa_family == AF_INET) &&
+			((family == AF_INET) || (family == 0))) {
+			struct sockaddr_in *addr =
+			(struct sockaddr_in *) curp->ifa_addr;
+
+			str = inet_ntop(AF_INET, &addr->sin_addr, tmp, 50);
+			if (str == NULL) {
+				strcpy(buffer, "inet_ntop failed\n");
+				error = 1;
+				goto getaddr_done;
+			}
+			if (offset == 0)
+				strcpy(buffer, tmp);
+			else
+				strcat(buffer, tmp);
+			strcat(buffer, ";");
+
+			offset += strlen(str) + 1;
+			if ((length - offset) < (ipv4_len + 1))
+				goto getaddr_done;
+
+		} else if ((family == AF_INET6) || (family == 0)) {
 
 			/*
 			 * We only support AF_INET and AF_INET6
 			 * and the list of addresses is separated by a ";".
 			 */
-				struct sockaddr_in6 *addr =
+			struct sockaddr_in6 *addr =
 				(struct sockaddr_in6 *) curp->ifa_addr;
 
-				str = inet_ntop(family,
+			str = inet_ntop(AF_INET6,
 					&addr->sin6_addr.s6_addr,
 					tmp, 50);
-				if (str == NULL) {
-					strcpy(buffer, "inet_ntop failed\n");
-					error = 1;
-					goto getaddr_done;
-				}
-				if (offset == 0)
-					strcpy(buffer, tmp);
-				else
-					strcat(buffer, tmp);
-				strcat(buffer, ";");
-				offset += strlen(str) + 1;
-				if ((length - offset) < (ipv6_len + 1))
-					goto getaddr_done;
-
+			if (str == NULL) {
+				strcpy(buffer, "inet_ntop failed\n");
+				error = 1;
+				goto getaddr_done;
 			}
+			if (offset == 0)
+				strcpy(buffer, tmp);
+			else
+				strcat(buffer, tmp);
+			strcat(buffer, ";");
+			offset += strlen(str) + 1;
+			if ((length - offset) < (ipv6_len + 1))
+				goto getaddr_done;
 
 		}
+
+
 		curp = curp->ifa_next;
 	}
 
@@ -812,13 +851,13 @@ int main(void)
 			strcpy(key_value, lic_version);
 			break;
 		case NetworkAddressIPv4:
-			kvp_get_ip_address(AF_INET, key_value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+			kvp_get_ip_address(AF_INET, NULL, KVP_OP_ENUMERATE,
+				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv4");
 			break;
 		case NetworkAddressIPv6:
-			kvp_get_ip_address(AF_INET6, key_value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+			kvp_get_ip_address(AF_INET6, NULL, KVP_OP_ENUMERATE,
+				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv6");
 			break;
 		case OSBuildNumber:
-- 
1.7.4.1


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

* [PATCH 05/15] Tools: hv: Prepare to expand kvp_get_ip_address() functionality
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

kvp_get_ip_address() implemented the functionality to retrieve IP address info.
Make this function more generic so that we could retrieve additional
per-interface information.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |  129 ++++++++++++++++++++++++++++++----------------
 1 files changed, 84 insertions(+), 45 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index ffe444b..3128e77 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -491,7 +491,8 @@ done:
 }
 
 static int
-kvp_get_ip_address(int family, char *buffer, int length)
+kvp_get_ip_address(int family, char *if_name, int op,
+		 void  *out_buffer, int length)
 {
 	struct ifaddrs *ifap;
 	struct ifaddrs *curp;
@@ -501,10 +502,19 @@ kvp_get_ip_address(int family, char *buffer, int length)
 	const char *str;
 	char tmp[50];
 	int error = 0;
-
+	char *buffer;
+	struct hv_kvp_ipaddr_value *ip_buffer;
+
+	if (op == KVP_OP_ENUMERATE) {
+		buffer = out_buffer;
+	} else {
+		ip_buffer = out_buffer;
+		buffer = (char *)ip_buffer->ip_addr;
+		ip_buffer->addr_family = 0;
+	}
 	/*
 	 * On entry into this function, the buffer is capable of holding the
-	 * maximum key value (2048 bytes).
+	 * maximum key value.
 	 */
 
 	if (getifaddrs(&ifap)) {
@@ -514,58 +524,87 @@ kvp_get_ip_address(int family, char *buffer, int length)
 
 	curp = ifap;
 	while (curp != NULL) {
-		if ((curp->ifa_addr != NULL) &&
-		   (curp->ifa_addr->sa_family == family)) {
-			if (family == AF_INET) {
-				struct sockaddr_in *addr =
-				(struct sockaddr_in *) curp->ifa_addr;
-
-				str = inet_ntop(family, &addr->sin_addr,
-						tmp, 50);
-				if (str == NULL) {
-					strcpy(buffer, "inet_ntop failed\n");
-					error = 1;
-					goto getaddr_done;
-				}
-				if (offset == 0)
-					strcpy(buffer, tmp);
-				else
-					strcat(buffer, tmp);
-				strcat(buffer, ";");
+		if (curp->ifa_addr == NULL) {
+			curp = curp->ifa_next;
+			continue;
+		}
 
-				offset += strlen(str) + 1;
-				if ((length - offset) < (ipv4_len + 1))
-					goto getaddr_done;
+		if ((if_name != NULL) &&
+			(strncmp(curp->ifa_name, if_name, strlen(if_name)))) {
+			/*
+			 * We want info about a specific interface;
+			 * just continue.
+			 */
+			curp = curp->ifa_next;
+			continue;
+		}
 
-			} else {
+		/*
+		 * We only support two address families: AF_INET and AF_INET6.
+		 * If a family value of 0 is specified, we collect both
+		 * supported address families; if not we gather info on
+		 * the specified address family.
+		 */
+		if ((family != 0) && (curp->ifa_addr->sa_family != family)) {
+			curp = curp->ifa_next;
+			continue;
+		}
+		if ((curp->ifa_addr->sa_family != AF_INET) &&
+			(curp->ifa_addr->sa_family != AF_INET6)) {
+			curp = curp->ifa_next;
+			continue;
+		}
+
+		if ((curp->ifa_addr->sa_family == AF_INET) &&
+			((family == AF_INET) || (family == 0))) {
+			struct sockaddr_in *addr =
+			(struct sockaddr_in *) curp->ifa_addr;
+
+			str = inet_ntop(AF_INET, &addr->sin_addr, tmp, 50);
+			if (str == NULL) {
+				strcpy(buffer, "inet_ntop failed\n");
+				error = 1;
+				goto getaddr_done;
+			}
+			if (offset == 0)
+				strcpy(buffer, tmp);
+			else
+				strcat(buffer, tmp);
+			strcat(buffer, ";");
+
+			offset += strlen(str) + 1;
+			if ((length - offset) < (ipv4_len + 1))
+				goto getaddr_done;
+
+		} else if ((family == AF_INET6) || (family == 0)) {
 
 			/*
 			 * We only support AF_INET and AF_INET6
 			 * and the list of addresses is separated by a ";".
 			 */
-				struct sockaddr_in6 *addr =
+			struct sockaddr_in6 *addr =
 				(struct sockaddr_in6 *) curp->ifa_addr;
 
-				str = inet_ntop(family,
+			str = inet_ntop(AF_INET6,
 					&addr->sin6_addr.s6_addr,
 					tmp, 50);
-				if (str == NULL) {
-					strcpy(buffer, "inet_ntop failed\n");
-					error = 1;
-					goto getaddr_done;
-				}
-				if (offset == 0)
-					strcpy(buffer, tmp);
-				else
-					strcat(buffer, tmp);
-				strcat(buffer, ";");
-				offset += strlen(str) + 1;
-				if ((length - offset) < (ipv6_len + 1))
-					goto getaddr_done;
-
+			if (str == NULL) {
+				strcpy(buffer, "inet_ntop failed\n");
+				error = 1;
+				goto getaddr_done;
 			}
+			if (offset == 0)
+				strcpy(buffer, tmp);
+			else
+				strcat(buffer, tmp);
+			strcat(buffer, ";");
+			offset += strlen(str) + 1;
+			if ((length - offset) < (ipv6_len + 1))
+				goto getaddr_done;
 
 		}
+
+
 		curp = curp->ifa_next;
 	}
 
@@ -812,13 +851,13 @@ int main(void)
 			strcpy(key_value, lic_version);
 			break;
 		case NetworkAddressIPv4:
-			kvp_get_ip_address(AF_INET, key_value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+			kvp_get_ip_address(AF_INET, NULL, KVP_OP_ENUMERATE,
+				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv4");
 			break;
 		case NetworkAddressIPv6:
-			kvp_get_ip_address(AF_INET6, key_value,
-					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+			kvp_get_ip_address(AF_INET6, NULL, KVP_OP_ENUMERATE,
+				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv6");
 			break;
 		case OSBuildNumber:
-- 
1.7.4.1

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

* [PATCH 06/15] Tools: hv: Further refactor kvp_get_ip_address()
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (4 preceding siblings ...)
  2012-07-14 20:34     ` K. Y. Srinivasan
@ 2012-07-14 20:34   ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                     ` (9 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

In preparation for making kvp_get_ip_address() more generic, factor out
the code for handling IP addresses.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   94 ++++++++++++++++++++-------------------------
 1 files changed, 42 insertions(+), 52 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 3128e77..218f28d 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -490,17 +490,50 @@ done:
 	return;
 }
 
+static int kvp_process_ip_address(void *addrp,
+				int family, char *buffer,
+				int length,  int *offset)
+{
+	struct sockaddr_in *addr;
+	struct sockaddr_in6 *addr6;
+	int addr_length;
+	char tmp[50];
+	const char *str;
+
+	if (family == AF_INET) {
+		addr = (struct sockaddr_in *)addrp;
+		str = inet_ntop(family, &addr->sin_addr, tmp, 50);
+		addr_length = INET_ADDRSTRLEN;
+	} else {
+		addr6 = (struct sockaddr_in6 *)addrp;
+		str = inet_ntop(family, &addr6->sin6_addr.s6_addr, tmp, 50);
+		addr_length = INET6_ADDRSTRLEN;
+	}
+
+	if ((length - *offset) < addr_length + 1)
+		return 1;
+	if (str == NULL) {
+		strcpy(buffer, "inet_ntop failed\n");
+		return 1;
+	}
+	if (*offset == 0)
+		strcpy(buffer, tmp);
+	else
+		strcat(buffer, tmp);
+	strcat(buffer, ";");
+
+	*offset += strlen(str) + 1;
+	return 0;
+}
+
 static int
 kvp_get_ip_address(int family, char *if_name, int op,
 		 void  *out_buffer, int length)
 {
 	struct ifaddrs *ifap;
 	struct ifaddrs *curp;
-	int ipv4_len = strlen("255.255.255.255") + 1;
-	int ipv6_len = strlen("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")+1;
 	int offset = 0;
 	const char *str;
-	char tmp[50];
 	int error = 0;
 	char *buffer;
 	struct hv_kvp_ipaddr_value *ip_buffer;
@@ -555,55 +588,12 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			continue;
 		}
 
-		if ((curp->ifa_addr->sa_family == AF_INET) &&
-			((family == AF_INET) || (family == 0))) {
-			struct sockaddr_in *addr =
-			(struct sockaddr_in *) curp->ifa_addr;
-
-			str = inet_ntop(AF_INET, &addr->sin_addr, tmp, 50);
-			if (str == NULL) {
-				strcpy(buffer, "inet_ntop failed\n");
-				error = 1;
-				goto getaddr_done;
-			}
-			if (offset == 0)
-				strcpy(buffer, tmp);
-			else
-				strcat(buffer, tmp);
-			strcat(buffer, ";");
-
-			offset += strlen(str) + 1;
-			if ((length - offset) < (ipv4_len + 1))
-				goto getaddr_done;
-
-		} else if ((family == AF_INET6) || (family == 0)) {
-
-			/*
-			 * We only support AF_INET and AF_INET6
-			 * and the list of addresses is separated by a ";".
-			 */
-			struct sockaddr_in6 *addr =
-				(struct sockaddr_in6 *) curp->ifa_addr;
-
-			str = inet_ntop(AF_INET6,
-					&addr->sin6_addr.s6_addr,
-					tmp, 50);
-			if (str == NULL) {
-				strcpy(buffer, "inet_ntop failed\n");
-				error = 1;
-				goto getaddr_done;
-			}
-			if (offset == 0)
-				strcpy(buffer, tmp);
-			else
-				strcat(buffer, tmp);
-			strcat(buffer, ";");
-			offset += strlen(str) + 1;
-			if ((length - offset) < (ipv6_len + 1))
-				goto getaddr_done;
-
-		}
-
+		error = kvp_process_ip_address(curp->ifa_addr,
+						curp->ifa_addr->sa_family,
+						buffer,
+						length, &offset);
+		if (error)
+			goto getaddr_done;
 
 		curp = curp->ifa_next;
 	}
-- 
1.7.4.1


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

* [PATCH 07/15] Tools: hv: Gather address family information
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Now, gather address family information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 218f28d..f687fa5 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -588,6 +588,17 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			continue;
 		}
 
+		if (op == KVP_OP_GET_IP_INFO) {
+			/*
+			 * Gather info other than the IP address.
+			 * IP address info will be gathered later.
+			 */
+			if (curp->ifa_addr->sa_family == AF_INET)
+				ip_buffer->addr_family |= ADDR_FAMILY_IPV4;
+			else
+				ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
+		}
+
 		error = kvp_process_ip_address(curp->ifa_addr,
 						curp->ifa_addr->sa_family,
 						buffer,
-- 
1.7.4.1


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

* [PATCH 07/15] Tools: hv: Gather address family information
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Now, gather address family information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 218f28d..f687fa5 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -588,6 +588,17 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			continue;
 		}
 
+		if (op == KVP_OP_GET_IP_INFO) {
+			/*
+			 * Gather info other than the IP address.
+			 * IP address info will be gathered later.
+			 */
+			if (curp->ifa_addr->sa_family == AF_INET)
+				ip_buffer->addr_family |= ADDR_FAMILY_IPV4;
+			else
+				ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
+		}
+
 		error = kvp_process_ip_address(curp->ifa_addr,
 						curp->ifa_addr->sa_family,
 						buffer,
-- 
1.7.4.1

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

* [PATCH 08/15] Tools: hv: Gather subnet information
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Now gather sub-net information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index f687fa5..07f6f7c 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -533,6 +533,7 @@ kvp_get_ip_address(int family, char *if_name, int op,
 	struct ifaddrs *ifap;
 	struct ifaddrs *curp;
 	int offset = 0;
+	int sn_offset = 0;
 	const char *str;
 	int error = 0;
 	char *buffer;
@@ -593,12 +594,38 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			 * Gather info other than the IP address.
 			 * IP address info will be gathered later.
 			 */
-			if (curp->ifa_addr->sa_family == AF_INET)
+			if (curp->ifa_addr->sa_family == AF_INET) {
 				ip_buffer->addr_family |= ADDR_FAMILY_IPV4;
-			else
+				/*
+				 * Get subnet info.
+				 */
+				error = kvp_process_ip_address(
+							curp->ifa_netmask,
+							AF_INET,
+							(char *)
+							ip_buffer->sub_net,
+							length,
+							&sn_offset);
+				if (error)
+					goto gather_ipaddr;
+			} else {
 				ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
+				/*
+				 * Get subnet info.
+				 */
+				error = kvp_process_ip_address(
+							curp->ifa_netmask,
+							AF_INET6,
+							(char *)
+							ip_buffer->sub_net,
+							length,
+							&sn_offset);
+				if (error)
+					goto gather_ipaddr;
+			}
 		}
 
+gather_ipaddr:
 		error = kvp_process_ip_address(curp->ifa_addr,
 						curp->ifa_addr->sa_family,
 						buffer,
-- 
1.7.4.1


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

* [PATCH 08/15] Tools: hv: Gather subnet information
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Now gather sub-net information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index f687fa5..07f6f7c 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -533,6 +533,7 @@ kvp_get_ip_address(int family, char *if_name, int op,
 	struct ifaddrs *ifap;
 	struct ifaddrs *curp;
 	int offset = 0;
+	int sn_offset = 0;
 	const char *str;
 	int error = 0;
 	char *buffer;
@@ -593,12 +594,38 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			 * Gather info other than the IP address.
 			 * IP address info will be gathered later.
 			 */
-			if (curp->ifa_addr->sa_family == AF_INET)
+			if (curp->ifa_addr->sa_family == AF_INET) {
 				ip_buffer->addr_family |= ADDR_FAMILY_IPV4;
-			else
+				/*
+				 * Get subnet info.
+				 */
+				error = kvp_process_ip_address(
+							curp->ifa_netmask,
+							AF_INET,
+							(char *)
+							ip_buffer->sub_net,
+							length,
+							&sn_offset);
+				if (error)
+					goto gather_ipaddr;
+			} else {
 				ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
+				/*
+				 * Get subnet info.
+				 */
+				error = kvp_process_ip_address(
+							curp->ifa_netmask,
+							AF_INET6,
+							(char *)
+							ip_buffer->sub_net,
+							length,
+							&sn_offset);
+				if (error)
+					goto gather_ipaddr;
+			}
 		}
 
+gather_ipaddr:
 		error = kvp_process_ip_address(curp->ifa_addr,
 						curp->ifa_addr->sa_family,
 						buffer,
-- 
1.7.4.1

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

* [PATCH 09/15] Tools: hv: Represent the ipv6 mask using CIDR notation
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (7 preceding siblings ...)
  2012-07-14 20:34     ` K. Y. Srinivasan
@ 2012-07-14 20:34   ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                     ` (6 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Transfor ipv6 subnet information to CIDR notation.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   45 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 07f6f7c..b9da130 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -490,6 +490,15 @@ done:
 	return;
 }
 
+static unsigned int hweight32(unsigned int *w)
+{
+	unsigned int res = *w - ((*w >> 1) & 0x55555555);
+	res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+	res = (res + (res >> 4)) & 0x0F0F0F0F;
+	res = res + (res >> 8);
+	return (res + (res >> 16)) & 0x000000FF;
+}
+
 static int kvp_process_ip_address(void *addrp,
 				int family, char *buffer,
 				int length,  int *offset)
@@ -534,10 +543,15 @@ kvp_get_ip_address(int family, char *if_name, int op,
 	struct ifaddrs *curp;
 	int offset = 0;
 	int sn_offset = 0;
-	const char *str;
 	int error = 0;
 	char *buffer;
 	struct hv_kvp_ipaddr_value *ip_buffer;
+	char cidr_mask[5]; /* /xyz */
+	int weight;
+	int i;
+	unsigned int *w;
+	char *sn_str;
+	struct sockaddr_in6 *addr6;
 
 	if (op == KVP_OP_ENUMERATE) {
 		buffer = out_buffer;
@@ -611,17 +625,28 @@ kvp_get_ip_address(int family, char *if_name, int op,
 			} else {
 				ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
 				/*
-				 * Get subnet info.
+				 * Get subnet info in CIDR format.
 				 */
-				error = kvp_process_ip_address(
-							curp->ifa_netmask,
-							AF_INET6,
-							(char *)
-							ip_buffer->sub_net,
-							length,
-							&sn_offset);
-				if (error)
+				weight = 0;
+				sn_str = (char *)ip_buffer->sub_net;
+				addr6 = (struct sockaddr_in6 *)
+					curp->ifa_netmask;
+				w = addr6->sin6_addr.s6_addr32;
+
+				for (i = 0; i < 4; i++)
+					weight += hweight32(&w[i]);
+
+				sprintf(cidr_mask, "/%d", weight);
+				if ((length - sn_offset) <
+					(strlen(cidr_mask) + 1))
 					goto gather_ipaddr;
+
+				if (sn_offset == 0)
+					strcpy(sn_str, cidr_mask);
+				else
+					strcat(sn_str, cidr_mask);
+				strcat((char *)ip_buffer->sub_net, ";");
+				sn_offset += strlen(sn_str) + 1;
 			}
 		}
 
-- 
1.7.4.1


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

* [PATCH 10/15] Tools: hv: Gather ipv[4,6] gateway information
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Gather information on the default gateways - ipv4/ipv6.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index b9da130..b7a2df0 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -490,6 +490,72 @@ done:
 	return;
 }
 
+static void kvp_process_ipconfig_file(char *cmd,
+					char *config_buf, int len,
+					int element_size, int offset)
+{
+	char buf[256];
+	char *p;
+	char *x;
+	FILE *file;
+
+	/*
+	 * First execute the command.
+	 */
+	file = popen(cmd, "r");
+	if (file == NULL)
+		return;
+
+	if (offset == 0)
+		memset(config_buf, 0, len);
+	while ((p = fgets(buf, sizeof(buf), file)) != NULL) {
+		if ((len - strlen(config_buf)) < (element_size + 1))
+			break;
+
+		x = strchr(p, '\n');
+		*x = '\0';
+		strcat(config_buf, p);
+		strcat(config_buf, ";");
+	}
+	pclose(file);
+}
+
+static void kvp_get_ipconfig_info(char *if_name,
+				 struct hv_kvp_ipaddr_value *buffer)
+{
+	char cmd[512];
+
+	/*
+	 * Get the address of default gateway (ipv4).
+	 */
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/ip -f inet  route | grep -w ");
+	strcat(cmd, if_name);
+	strcat(cmd, " | awk '/default/ {print $3 }'");
+
+	/*
+	 * Execute the command to gather gateway info.
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
+				(MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
+
+	/*
+	 * Get the address of default gateway (ipv6).
+	 */
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/ip -f inet6  route | grep -w ");
+	strcat(cmd, if_name);
+	strcat(cmd, " | awk '/default/ {print $3 }'");
+
+	/*
+	 * Execute the command to gather gateway info (ipv6).
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
+				(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
+
+}
+
+
 static unsigned int hweight32(unsigned int *w)
 {
 	unsigned int res = *w - ((*w >> 1) & 0x55555555);
@@ -648,6 +714,12 @@ kvp_get_ip_address(int family, char *if_name, int op,
 				strcat((char *)ip_buffer->sub_net, ";");
 				sn_offset += strlen(sn_str) + 1;
 			}
+
+			/*
+			 * Collect other ip related configuration info.
+			 */
+
+			kvp_get_ipconfig_info(if_name, ip_buffer);
 		}
 
 gather_ipaddr:
-- 
1.7.4.1


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

* [PATCH 10/15] Tools: hv: Gather ipv[4,6] gateway information
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Gather information on the default gateways - ipv4/ipv6.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index b9da130..b7a2df0 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -490,6 +490,72 @@ done:
 	return;
 }
 
+static void kvp_process_ipconfig_file(char *cmd,
+					char *config_buf, int len,
+					int element_size, int offset)
+{
+	char buf[256];
+	char *p;
+	char *x;
+	FILE *file;
+
+	/*
+	 * First execute the command.
+	 */
+	file = popen(cmd, "r");
+	if (file == NULL)
+		return;
+
+	if (offset == 0)
+		memset(config_buf, 0, len);
+	while ((p = fgets(buf, sizeof(buf), file)) != NULL) {
+		if ((len - strlen(config_buf)) < (element_size + 1))
+			break;
+
+		x = strchr(p, '\n');
+		*x = '\0';
+		strcat(config_buf, p);
+		strcat(config_buf, ";");
+	}
+	pclose(file);
+}
+
+static void kvp_get_ipconfig_info(char *if_name,
+				 struct hv_kvp_ipaddr_value *buffer)
+{
+	char cmd[512];
+
+	/*
+	 * Get the address of default gateway (ipv4).
+	 */
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/ip -f inet  route | grep -w ");
+	strcat(cmd, if_name);
+	strcat(cmd, " | awk '/default/ {print $3 }'");
+
+	/*
+	 * Execute the command to gather gateway info.
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
+				(MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
+
+	/*
+	 * Get the address of default gateway (ipv6).
+	 */
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/ip -f inet6  route | grep -w ");
+	strcat(cmd, if_name);
+	strcat(cmd, " | awk '/default/ {print $3 }'");
+
+	/*
+	 * Execute the command to gather gateway info (ipv6).
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
+				(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
+
+}
+
+
 static unsigned int hweight32(unsigned int *w)
 {
 	unsigned int res = *w - ((*w >> 1) & 0x55555555);
@@ -648,6 +714,12 @@ kvp_get_ip_address(int family, char *if_name, int op,
 				strcat((char *)ip_buffer->sub_net, ";");
 				sn_offset += strlen(sn_str) + 1;
 			}
+
+			/*
+			 * Collect other ip related configuration info.
+			 */
+
+			kvp_get_ipconfig_info(if_name, ip_buffer);
 		}
 
 gather_ipaddr:
-- 
1.7.4.1

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

* [PATCH 11/15] Tools: hv: Gather DNS information
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Now gather DNS information. This information cannot be gathered in
a distro independent fashion. Invoke an external script (that can be
distro dependent) to gather the DNS information.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index b7a2df0..a81ce67 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -553,6 +553,33 @@ static void kvp_get_ipconfig_info(char *if_name,
 	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
 				(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
 
+
+	/*
+	 * Gather the DNS  state.
+	 * Since there is no standard way to get this information
+	 * across various distributions of interest; we just invoke
+	 * an external script that needs to be ported across distros
+	 * of interest.
+	 * Input to the script:
+	 * 1) Interface name
+	 *
+	 * Following is the expected format of the information from the script:
+	 *
+	 * ipaddr1 (nameserver1)
+	 * ipaddr2 (nameserver2)
+	 * .
+	 * .
+	 */
+
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/hv_get_dns_info ");
+	strcat(cmd, if_name);
+
+	/*
+	 * Execute the command to gather DNS info.
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
+				(MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
 }
 
 
-- 
1.7.4.1


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

* [PATCH 11/15] Tools: hv: Gather DNS information
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Now gather DNS information. This information cannot be gathered in
a distro independent fashion. Invoke an external script (that can be
distro dependent) to gather the DNS information.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index b7a2df0..a81ce67 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -553,6 +553,33 @@ static void kvp_get_ipconfig_info(char *if_name,
 	kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
 				(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
 
+
+	/*
+	 * Gather the DNS  state.
+	 * Since there is no standard way to get this information
+	 * across various distributions of interest; we just invoke
+	 * an external script that needs to be ported across distros
+	 * of interest.
+	 * Input to the script:
+	 * 1) Interface name
+	 *
+	 * Following is the expected format of the information from the script:
+	 *
+	 * ipaddr1 (nameserver1)
+	 * ipaddr2 (nameserver2)
+	 * .
+	 * .
+	 */
+
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/hv_get_dns_info ");
+	strcat(cmd, if_name);
+
+	/*
+	 * Execute the command to gather DNS info.
+	 */
+	kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
+				(MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
 }
 
 
-- 
1.7.4.1

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

* [PATCH 12/15] Tools: hv: Gather DHCP information
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (10 preceding siblings ...)
  2012-07-14 20:34     ` K. Y. Srinivasan
@ 2012-07-14 20:34   ` K. Y. Srinivasan
  2012-07-14 21:36     ` richard -rw- weinberger
  2012-07-14 20:34     ` K. Y. Srinivasan
                     ` (3 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Collect information on dhcp setting for the specified interface.
We invoke an exyernal script to get this information.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index a81ce67..c510283 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -524,6 +524,9 @@ static void kvp_get_ipconfig_info(char *if_name,
 				 struct hv_kvp_ipaddr_value *buffer)
 {
 	char cmd[512];
+	char dhcp_info[128];
+	char *p;
+	FILE *file;
 
 	/*
 	 * Get the address of default gateway (ipv4).
@@ -580,6 +583,36 @@ static void kvp_get_ipconfig_info(char *if_name,
 	 */
 	kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
 				(MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
+
+	/*
+	 * Gather the DHCP state.
+	 * We will gather this state by invoking an external script.
+	 * The parameter to the script is the interface name.
+	 * Here is the expected output:
+	 *
+	 * Enabled: DHCP enabled.
+	 */
+
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/hv_get_dhcp_info ");
+	strcat(cmd, if_name);
+
+	file = popen(cmd, "r");
+	if (file == NULL)
+		return;
+
+	p = fgets(dhcp_info, sizeof(dhcp_info), file);
+	if (p == NULL) {
+		pclose(file);
+		return;
+	}
+
+	if (!strncmp(p, "Enabled", 7))
+		buffer->dhcp_enabled = 1;
+	else
+		buffer->dhcp_enabled = 0;
+
+	pclose(file);
 }
 
 
-- 
1.7.4.1


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

* [PATCH 13/15] Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  2012-07-14 20:34     ` K. Y. Srinivasan
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Implement the KVP verb - KVP_OP_SET_IP_INFO. This operation configures the 
specified interface based on the given configuration. Since configuring
an interface is very distro specific, we invoke an external script to
configure the interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |  324 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index c510283..c33fc8e 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -41,6 +41,7 @@
 #include <syslog.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <dirent.h>
 
 /*
  * KVP protocol: The user mode component first registers with the
@@ -490,6 +491,105 @@ done:
 	return;
 }
 
+
+/*
+ * Retrieve an interface name corresponding to the specified guid.
+ * If there is a match, the function returns a pointer
+ * to the interface name and if not, a NULL is returned.
+ * If a match is found, the caller is responsible for
+ * freeing the memory.
+ */
+
+static char *kvp_get_if_name(char *guid)
+{
+	DIR *dir;
+	struct dirent *entry;
+	FILE    *file;
+	char    *p, *q, *x;
+	char    *if_name = NULL;
+	char    buf[256];
+	char *kvp_net_dir = "/sys/class/net/";
+	char dev_id[100];
+
+	dir = opendir(kvp_net_dir);
+	if (dir == NULL)
+		return NULL;
+
+	memset(dev_id, 0, sizeof(dev_id));
+	strcat(dev_id, kvp_net_dir);
+	q = dev_id + strlen(kvp_net_dir);
+
+	while ((entry = readdir(dir)) != NULL) {
+		/*
+		 * Set the state for the next pass.
+		 */
+		*q = '\0';
+		strcat(dev_id, entry->d_name);
+		strcat(dev_id, "/device/device_id");
+
+		file = fopen(dev_id, "r");
+		if (file == NULL)
+			continue;
+
+		p = fgets(buf, sizeof(buf), file);
+		if (p) {
+			x = strchr(p, '\n');
+			if (x)
+				*x = '\0';
+
+			if (!strcmp(p, guid)) {
+				/*
+				 * Found the guid match; return the interface
+				 * name. The caller will free the memory.
+				 */
+				if_name = strdup(entry->d_name);
+				break;
+			}
+		}
+		fclose(file);
+	}
+
+	closedir(dir);
+	return if_name;
+}
+
+/*
+ * Retrieve the MAC address given the interface name.
+ */
+
+static char *kvp_if_name_to_mac(char *if_name)
+{
+	FILE    *file;
+	char    *p, *x;
+	char    buf[256];
+	char addr_file[100];
+	int i;
+	char *mac_addr = NULL;
+
+	memset(addr_file, 0, sizeof(addr_file));
+	strcat(addr_file, "/sys/class/net/");
+	strcat(addr_file, if_name);
+	strcat(addr_file, "/address");
+
+	file = fopen(addr_file, "r");
+	if (file == NULL)
+		return NULL;
+
+	p = fgets(buf, sizeof(buf), file);
+	if (p) {
+		x = strchr(p, '\n');
+		if (x)
+			*x = '\0';
+		for (i = 0; i < strlen(p); i++)
+			p[i] = toupper(p[i]);
+		mac_addr = strdup(p);
+	}
+
+	fclose(file);
+	return mac_addr;
+}
+
+
 static void kvp_process_ipconfig_file(char *cmd,
 					char *config_buf, int len,
 					int element_size, int offset)
@@ -799,6 +899,207 @@ getaddr_done:
 }
 
 
+int parse_ip_val_buffer(char *in_buf, int *offset, char *out_buf, int out_len)
+{
+	char *x;
+	char *start;
+
+	/*
+	 * in_buf has sequence of characters that are seperated by
+	 * the character ';'. The last sequence is terminated by ';'.
+	 */
+	start = in_buf + *offset;
+
+	x = strchr(start, ';');
+	if (x) {
+		*x = 0;
+		if ((x - start) <= out_len) {
+			strcpy(out_buf, start);
+			strcat(out_buf, "\n");
+			*offset = (x - start) + 1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
+{
+	int error = 0;
+	char if_file[50];
+	FILE *file;
+	char addr[INET6_ADDRSTRLEN];
+	int i;
+	char str[256];
+	char sub_str[10];
+	int offset;
+	char cmd[512];
+	char *mac_addr;
+
+	/*
+	 * Set the configuration for the specified interface with
+	 * the information provided. Since there is no standard
+	 * way to configure an interface, we will have an external
+	 * script that does the job of configuring the interface and
+	 * flushing the configuration.
+	 *
+	 * The parameters passed to this external script are:
+	 * 1. A configuration file that has the specified configuration.
+	 *
+	 * We will embed the name of the interface in the configuration
+	 * file: ifcfg-ethx (where ethx is the interface name).
+	 *
+	 * Here is the format of the ip configuration file:
+	 *
+	 * HWADDR=macaddr
+	 * BOOTPROTO=dhcp (dhcp enabled for the interface)
+	 * IPADDR_x=ipaddr
+	 * NETMASK_x=netmask
+	 * GATEWAY_x=gateway
+	 * DNSx=dns
+	 */
+
+	memset(if_file, 0, sizeof(if_file));
+	strcat(if_file, "/var/opt/hyperv/ifcfg-");
+	strcat(if_file, if_name);
+
+	file = fopen(if_file, "w");
+
+	if (file == NULL)
+		return 1;
+
+	/*
+	 * First write out the MAC address.
+	 */
+
+	mac_addr = kvp_if_name_to_mac(if_name);
+	if (mac_addr == NULL) {
+		error = 1;
+		goto setval_error;
+	}
+
+	memset(str, 0, sizeof(str));
+	strcat(str, "HWADDR=");
+	strcat(str, mac_addr);
+	strcat(str, "\n");
+	error = fputs(str, file);
+	if (error == EOF)
+		goto setval_error;
+
+	if (new_val->dhcp_enabled) {
+		error = fputs("BOOTPROTO=dhcp\n", file);
+		if (error == EOF)
+			goto setval_error;
+
+		/*
+		 * We are done!.
+		 */
+		goto setval_done;
+	}
+
+	/*
+	 * Write the configuration for ipaddress, netmask, gateway and
+	 * name servers.
+	 */
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->ip_addr, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		strcat(str, "IPADDR");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->sub_net, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		sprintf(str, "NETMAK");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->gate_way, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		sprintf(str, "GATEWAY");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 1;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->dns_addr, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		sprintf(str, "DNS%d=", i++);
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+
+setval_done:
+	free(mac_addr);
+	fclose(file);
+
+	/*
+	 * Now that we have populated the configuration file,
+	 * invoke the external script to do its magic.
+	 */
+
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/hv_set_ifconfig ");
+	strcat(cmd, if_file);
+	system(cmd);
+	return 0;
+
+setval_error:
+	free(mac_addr);
+	fclose(file);
+	return error;
+}
+
+
 static int
 kvp_get_domain_name(char *buffer, int length)
 {
@@ -868,6 +1169,8 @@ int main(void)
 	char	*key_name;
 	int	op;
 	int	pool;
+	char	*if_name;
+	struct hv_kvp_ipaddr_value *kvp_ip_val;
 
 	daemon(1, 0);
 	openlog("KVP", 0, LOG_USER);
@@ -969,6 +1272,27 @@ int main(void)
 			}
 			continue;
 
+		case KVP_OP_SET_IP_INFO:
+			kvp_ip_val = &hv_msg->body.kvp_ip_val;
+			if_name = kvp_get_if_name(
+					(char *)kvp_ip_val->adapter_id);
+			if (if_name == NULL) {
+				/*
+				 * We could not map the guid to an
+				 * interface name; return error.
+				 */
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+				break;
+			}
+			error = kvp_set_ip_info(if_name, kvp_ip_val);
+			if (error)
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+
+			free(if_name);
+			break;
+
 		case KVP_OP_SET:
 			if (kvp_key_add_or_modify(pool,
 					hv_msg->body.kvp_set.data.key,
-- 
1.7.4.1


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

* [PATCH 13/15] Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO
@ 2012-07-14 20:34     ` K. Y. Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw

Implement the KVP verb - KVP_OP_SET_IP_INFO. This operation configures the 
specified interface based on the given configuration. Since configuring
an interface is very distro specific, we invoke an external script to
configure the interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |  324 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index c510283..c33fc8e 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -41,6 +41,7 @@
 #include <syslog.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <dirent.h>
 
 /*
  * KVP protocol: The user mode component first registers with the
@@ -490,6 +491,105 @@ done:
 	return;
 }
 
+
+/*
+ * Retrieve an interface name corresponding to the specified guid.
+ * If there is a match, the function returns a pointer
+ * to the interface name and if not, a NULL is returned.
+ * If a match is found, the caller is responsible for
+ * freeing the memory.
+ */
+
+static char *kvp_get_if_name(char *guid)
+{
+	DIR *dir;
+	struct dirent *entry;
+	FILE    *file;
+	char    *p, *q, *x;
+	char    *if_name = NULL;
+	char    buf[256];
+	char *kvp_net_dir = "/sys/class/net/";
+	char dev_id[100];
+
+	dir = opendir(kvp_net_dir);
+	if (dir == NULL)
+		return NULL;
+
+	memset(dev_id, 0, sizeof(dev_id));
+	strcat(dev_id, kvp_net_dir);
+	q = dev_id + strlen(kvp_net_dir);
+
+	while ((entry = readdir(dir)) != NULL) {
+		/*
+		 * Set the state for the next pass.
+		 */
+		*q = '\0';
+		strcat(dev_id, entry->d_name);
+		strcat(dev_id, "/device/device_id");
+
+		file = fopen(dev_id, "r");
+		if (file == NULL)
+			continue;
+
+		p = fgets(buf, sizeof(buf), file);
+		if (p) {
+			x = strchr(p, '\n');
+			if (x)
+				*x = '\0';
+
+			if (!strcmp(p, guid)) {
+				/*
+				 * Found the guid match; return the interface
+				 * name. The caller will free the memory.
+				 */
+				if_name = strdup(entry->d_name);
+				break;
+			}
+		}
+		fclose(file);
+	}
+
+	closedir(dir);
+	return if_name;
+}
+
+/*
+ * Retrieve the MAC address given the interface name.
+ */
+
+static char *kvp_if_name_to_mac(char *if_name)
+{
+	FILE    *file;
+	char    *p, *x;
+	char    buf[256];
+	char addr_file[100];
+	int i;
+	char *mac_addr = NULL;
+
+	memset(addr_file, 0, sizeof(addr_file));
+	strcat(addr_file, "/sys/class/net/");
+	strcat(addr_file, if_name);
+	strcat(addr_file, "/address");
+
+	file = fopen(addr_file, "r");
+	if (file == NULL)
+		return NULL;
+
+	p = fgets(buf, sizeof(buf), file);
+	if (p) {
+		x = strchr(p, '\n');
+		if (x)
+			*x = '\0';
+		for (i = 0; i < strlen(p); i++)
+			p[i] = toupper(p[i]);
+		mac_addr = strdup(p);
+	}
+
+	fclose(file);
+	return mac_addr;
+}
+
+
 static void kvp_process_ipconfig_file(char *cmd,
 					char *config_buf, int len,
 					int element_size, int offset)
@@ -799,6 +899,207 @@ getaddr_done:
 }
 
 
+int parse_ip_val_buffer(char *in_buf, int *offset, char *out_buf, int out_len)
+{
+	char *x;
+	char *start;
+
+	/*
+	 * in_buf has sequence of characters that are seperated by
+	 * the character ';'. The last sequence is terminated by ';'.
+	 */
+	start = in_buf + *offset;
+
+	x = strchr(start, ';');
+	if (x) {
+		*x = 0;
+		if ((x - start) <= out_len) {
+			strcpy(out_buf, start);
+			strcat(out_buf, "\n");
+			*offset = (x - start) + 1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
+{
+	int error = 0;
+	char if_file[50];
+	FILE *file;
+	char addr[INET6_ADDRSTRLEN];
+	int i;
+	char str[256];
+	char sub_str[10];
+	int offset;
+	char cmd[512];
+	char *mac_addr;
+
+	/*
+	 * Set the configuration for the specified interface with
+	 * the information provided. Since there is no standard
+	 * way to configure an interface, we will have an external
+	 * script that does the job of configuring the interface and
+	 * flushing the configuration.
+	 *
+	 * The parameters passed to this external script are:
+	 * 1. A configuration file that has the specified configuration.
+	 *
+	 * We will embed the name of the interface in the configuration
+	 * file: ifcfg-ethx (where ethx is the interface name).
+	 *
+	 * Here is the format of the ip configuration file:
+	 *
+	 * HWADDR=macaddr
+	 * BOOTPROTO=dhcp (dhcp enabled for the interface)
+	 * IPADDR_x=ipaddr
+	 * NETMASK_x=netmask
+	 * GATEWAY_x=gateway
+	 * DNSx=dns
+	 */
+
+	memset(if_file, 0, sizeof(if_file));
+	strcat(if_file, "/var/opt/hyperv/ifcfg-");
+	strcat(if_file, if_name);
+
+	file = fopen(if_file, "w");
+
+	if (file == NULL)
+		return 1;
+
+	/*
+	 * First write out the MAC address.
+	 */
+
+	mac_addr = kvp_if_name_to_mac(if_name);
+	if (mac_addr == NULL) {
+		error = 1;
+		goto setval_error;
+	}
+
+	memset(str, 0, sizeof(str));
+	strcat(str, "HWADDR=");
+	strcat(str, mac_addr);
+	strcat(str, "\n");
+	error = fputs(str, file);
+	if (error == EOF)
+		goto setval_error;
+
+	if (new_val->dhcp_enabled) {
+		error = fputs("BOOTPROTO=dhcp\n", file);
+		if (error == EOF)
+			goto setval_error;
+
+		/*
+		 * We are done!.
+		 */
+		goto setval_done;
+	}
+
+	/*
+	 * Write the configuration for ipaddress, netmask, gateway and
+	 * name servers.
+	 */
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->ip_addr, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		strcat(str, "IPADDR");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->sub_net, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		sprintf(str, "NETMAK");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 0;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->gate_way, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		memset(sub_str, 0, sizeof(sub_str));
+		sprintf(str, "GATEWAY");
+		if (i != 0)
+			sprintf(sub_str, "_%d", i);
+		strcat(str, sub_str);
+		i++;
+		strcat(str, "=");
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+	i = 1;
+	offset = 0;
+	memset(addr, 0, sizeof(addr));
+	memset(str, 0, sizeof(str));
+
+	while (parse_ip_val_buffer((char *)new_val->dns_addr, &offset, addr,
+					(MAX_IP_ADDR_SIZE * 2))) {
+		sprintf(str, "DNS%d=", i++);
+		strcat(str, addr);
+		error = fputs(str, file);
+		if (error == EOF)
+			goto setval_error;
+	}
+
+
+setval_done:
+	free(mac_addr);
+	fclose(file);
+
+	/*
+	 * Now that we have populated the configuration file,
+	 * invoke the external script to do its magic.
+	 */
+
+	memset(cmd, 0, 512);
+	strcat(cmd, "/sbin/hv_set_ifconfig ");
+	strcat(cmd, if_file);
+	system(cmd);
+	return 0;
+
+setval_error:
+	free(mac_addr);
+	fclose(file);
+	return error;
+}
+
+
 static int
 kvp_get_domain_name(char *buffer, int length)
 {
@@ -868,6 +1169,8 @@ int main(void)
 	char	*key_name;
 	int	op;
 	int	pool;
+	char	*if_name;
+	struct hv_kvp_ipaddr_value *kvp_ip_val;
 
 	daemon(1, 0);
 	openlog("KVP", 0, LOG_USER);
@@ -969,6 +1272,27 @@ int main(void)
 			}
 			continue;
 
+		case KVP_OP_SET_IP_INFO:
+			kvp_ip_val = &hv_msg->body.kvp_ip_val;
+			if_name = kvp_get_if_name(
+					(char *)kvp_ip_val->adapter_id);
+			if (if_name == NULL) {
+				/*
+				 * We could not map the guid to an
+				 * interface name; return error.
+				 */
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+				break;
+			}
+			error = kvp_set_ip_info(if_name, kvp_ip_val);
+			if (error)
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+
+			free(if_name);
+			break;
+
 		case KVP_OP_SET:
 			if (kvp_key_add_or_modify(pool,
 					hv_msg->body.kvp_set.data.key,
-- 
1.7.4.1

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

* [PATCH 14/15] Tools: hv: Rename the function kvp_get_ip_address()
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (12 preceding siblings ...)
  2012-07-14 20:34     ` K. Y. Srinivasan
@ 2012-07-14 20:34   ` K. Y. Srinivasan
  2012-07-14 20:34   ` [PATCH 15/15] Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO K. Y. Srinivasan
  2012-07-17 16:04   ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards Greg KH
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Rename the function kvp_get_ip_address().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index c33fc8e..6d224e7 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -762,7 +762,7 @@ static int kvp_process_ip_address(void *addrp,
 }
 
 static int
-kvp_get_ip_address(int family, char *if_name, int op,
+kvp_get_ip_info(int family, char *if_name, int op,
 		 void  *out_buffer, int length)
 {
 	struct ifaddrs *ifap;
@@ -1360,12 +1360,12 @@ int main(void)
 			strcpy(key_value, lic_version);
 			break;
 		case NetworkAddressIPv4:
-			kvp_get_ip_address(AF_INET, NULL, KVP_OP_ENUMERATE,
+			kvp_get_ip_info(AF_INET, NULL, KVP_OP_ENUMERATE,
 				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv4");
 			break;
 		case NetworkAddressIPv6:
-			kvp_get_ip_address(AF_INET6, NULL, KVP_OP_ENUMERATE,
+			kvp_get_ip_info(AF_INET6, NULL, KVP_OP_ENUMERATE,
 				key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
 			strcpy(key_name, "NetworkAddressIPv6");
 			break;
-- 
1.7.4.1


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

* [PATCH 15/15] Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (13 preceding siblings ...)
  2012-07-14 20:34   ` [PATCH 14/15] Tools: hv: Rename the function kvp_get_ip_address() K. Y. Srinivasan
@ 2012-07-14 20:34   ` K. Y. Srinivasan
  2012-07-17 16:04   ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards Greg KH
  15 siblings, 0 replies; 45+ messages in thread
From: K. Y. Srinivasan @ 2012-07-14 20:34 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization, olaf, apw; +Cc: K. Y. Srinivasan

Now implement the KVP verb - KVP_OP_GET_IP_INFO. This operation retrieves IP
information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 tools/hv/hv_kvp_daemon.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 6d224e7..723e78e 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -590,6 +590,69 @@ static char *kvp_if_name_to_mac(char *if_name)
 }
 
 
+/*
+ * Retrieve the interface name given tha MAC address.
+ */
+
+static char *kvp_mac_to_if_name(char *mac)
+{
+	DIR *dir;
+	struct dirent *entry;
+	FILE    *file;
+	char    *p, *q, *x;
+	char    *if_name = NULL;
+	char    buf[256];
+	char *kvp_net_dir = "/sys/class/net/";
+	char dev_id[100];
+	int i;
+
+	dir = opendir(kvp_net_dir);
+	if (dir == NULL)
+		return NULL;
+
+	memset(dev_id, 0, sizeof(dev_id));
+	strcat(dev_id, kvp_net_dir);
+	q = dev_id + strlen(kvp_net_dir);
+
+	while ((entry = readdir(dir)) != NULL) {
+		/*
+		 * Set the state for the next pass.
+		 */
+		*q = '\0';
+
+		strcat(dev_id, entry->d_name);
+		strcat(dev_id, "/address");
+
+		file = fopen(dev_id, "r");
+		if (file == NULL)
+			continue;
+
+		p = fgets(buf, sizeof(buf), file);
+		if (p) {
+			x = strchr(p, '\n');
+			if (x)
+				*x = '\0';
+
+			for (i = 0; i < strlen(p); i++)
+				p[i] = toupper(p[i]);
+
+			if (!strcmp(p, mac)) {
+				/*
+				 * Found the MAC match; return the interface
+				 * name. The caller will free the memory.
+				 */
+				if_name = strdup(entry->d_name);
+				break;
+			}
+		}
+		fclose(file);
+	}
+
+	closedir(dir);
+	return if_name;
+}
+
+
 static void kvp_process_ipconfig_file(char *cmd,
 					char *config_buf, int len,
 					int element_size, int offset)
@@ -1272,6 +1335,32 @@ int main(void)
 			}
 			continue;
 
+		case KVP_OP_GET_IP_INFO:
+			kvp_ip_val = &hv_msg->body.kvp_ip_val;
+			if_name =
+			kvp_mac_to_if_name((char *)kvp_ip_val->adapter_id);
+
+			if (if_name == NULL) {
+				/*
+				 * We could not map the mac address to an
+				 * interface name; return error.
+				 */
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+				break;
+			}
+			error = kvp_get_ip_info(
+						0, if_name, KVP_OP_GET_IP_INFO,
+						kvp_ip_val,
+						(MAX_IP_ADDR_SIZE * 2));
+
+			if (error)
+				*((int *)(&hv_msg->kvp_hdr.operation)) =
+					HV_ERROR_DEVICE_NOT_CONNECTED;
+
+			free(if_name);
+			break;
+
 		case KVP_OP_SET_IP_INFO:
 			kvp_ip_val = &hv_msg->body.kvp_ip_val;
 			if_name = kvp_get_if_name(
-- 
1.7.4.1


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

* Re: [PATCH 12/15] Tools: hv: Gather DHCP information
  2012-07-14 20:34   ` [PATCH 12/15] Tools: hv: Gather DHCP information K. Y. Srinivasan
@ 2012-07-14 21:36     ` richard -rw- weinberger
  2012-07-14 23:02         ` KY Srinivasan
  0 siblings, 1 reply; 45+ messages in thread
From: richard -rw- weinberger @ 2012-07-14 21:36 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw

On Sat, Jul 14, 2012 at 10:34 PM, K. Y. Srinivasan <kys@microsoft.com> wrote:
> Collect information on dhcp setting for the specified interface.
> We invoke an exyernal script to get this information.
>
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  tools/hv/hv_kvp_daemon.c |   33 +++++++++++++++++++++++++++++++++
>  1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
> index a81ce67..c510283 100644
> --- a/tools/hv/hv_kvp_daemon.c
> +++ b/tools/hv/hv_kvp_daemon.c
> @@ -524,6 +524,9 @@ static void kvp_get_ipconfig_info(char *if_name,
>                                  struct hv_kvp_ipaddr_value *buffer)
>  {
>         char cmd[512];
> +       char dhcp_info[128];
> +       char *p;
> +       FILE *file;
>
>         /*
>          * Get the address of default gateway (ipv4).
> @@ -580,6 +583,36 @@ static void kvp_get_ipconfig_info(char *if_name,
>          */
>         kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
>                                 (MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
> +
> +       /*
> +        * Gather the DHCP state.
> +        * We will gather this state by invoking an external script.
> +        * The parameter to the script is the interface name.
> +        * Here is the expected output:
> +        *
> +        * Enabled: DHCP enabled.
> +        */
> +
> +       memset(cmd, 0, 512);

Why not sizeof(cmd)?

> +       strcat(cmd, "/sbin/hv_get_dhcp_info ");
> +       strcat(cmd, if_name);

What about strncat()?

-- 
Thanks,
//richard

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

* RE: [PATCH 12/15] Tools: hv: Gather DHCP information
  2012-07-14 21:36     ` richard -rw- weinberger
@ 2012-07-14 23:02         ` KY Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-14 23:02 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw



> -----Original Message-----
> From: richard -rw- weinberger [mailto:richard.weinberger@gmail.com]
> Sent: Saturday, July 14, 2012 5:37 PM
> To: KY Srinivasan
> Cc: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; olaf@aepfle.de;
> apw@canonical.com
> Subject: Re: [PATCH 12/15] Tools: hv: Gather DHCP information
> 
> On Sat, Jul 14, 2012 at 10:34 PM, K. Y. Srinivasan <kys@microsoft.com> wrote:
> > Collect information on dhcp setting for the specified interface.
> > We invoke an exyernal script to get this information.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  tools/hv/hv_kvp_daemon.c |   33 +++++++++++++++++++++++++++++++++
> >  1 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
> > index a81ce67..c510283 100644
> > --- a/tools/hv/hv_kvp_daemon.c
> > +++ b/tools/hv/hv_kvp_daemon.c
> > @@ -524,6 +524,9 @@ static void kvp_get_ipconfig_info(char *if_name,
> >                                  struct hv_kvp_ipaddr_value *buffer)
> >  {
> >         char cmd[512];
> > +       char dhcp_info[128];
> > +       char *p;
> > +       FILE *file;
> >
> >         /*
> >          * Get the address of default gateway (ipv4).
> > @@ -580,6 +583,36 @@ static void kvp_get_ipconfig_info(char *if_name,
> >          */
> >         kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
> >                                 (MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
> > +
> > +       /*
> > +        * Gather the DHCP state.
> > +        * We will gather this state by invoking an external script.
> > +        * The parameter to the script is the interface name.
> > +        * Here is the expected output:
> > +        *
> > +        * Enabled: DHCP enabled.
> > +        */
> > +
> > +       memset(cmd, 0, 512);
> 
> Why not sizeof(cmd)?

I have a bunch of other cleanups lined up for this user level daemon. If it is
ok with you, I could address this as part of that patch set. However, if 
there are more substantive changes needed in this patch-set, I will
also address this. 

Thank you,

K. Y




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

* RE: [PATCH 12/15] Tools: hv: Gather DHCP information
@ 2012-07-14 23:02         ` KY Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-14 23:02 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: olaf, gregkh, linux-kernel, virtualization, apw, devel



> -----Original Message-----
> From: richard -rw- weinberger [mailto:richard.weinberger@gmail.com]
> Sent: Saturday, July 14, 2012 5:37 PM
> To: KY Srinivasan
> Cc: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; olaf@aepfle.de;
> apw@canonical.com
> Subject: Re: [PATCH 12/15] Tools: hv: Gather DHCP information
> 
> On Sat, Jul 14, 2012 at 10:34 PM, K. Y. Srinivasan <kys@microsoft.com> wrote:
> > Collect information on dhcp setting for the specified interface.
> > We invoke an exyernal script to get this information.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  tools/hv/hv_kvp_daemon.c |   33 +++++++++++++++++++++++++++++++++
> >  1 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
> > index a81ce67..c510283 100644
> > --- a/tools/hv/hv_kvp_daemon.c
> > +++ b/tools/hv/hv_kvp_daemon.c
> > @@ -524,6 +524,9 @@ static void kvp_get_ipconfig_info(char *if_name,
> >                                  struct hv_kvp_ipaddr_value *buffer)
> >  {
> >         char cmd[512];
> > +       char dhcp_info[128];
> > +       char *p;
> > +       FILE *file;
> >
> >         /*
> >          * Get the address of default gateway (ipv4).
> > @@ -580,6 +583,36 @@ static void kvp_get_ipconfig_info(char *if_name,
> >          */
> >         kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
> >                                 (MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
> > +
> > +       /*
> > +        * Gather the DHCP state.
> > +        * We will gather this state by invoking an external script.
> > +        * The parameter to the script is the interface name.
> > +        * Here is the expected output:
> > +        *
> > +        * Enabled: DHCP enabled.
> > +        */
> > +
> > +       memset(cmd, 0, 512);
> 
> Why not sizeof(cmd)?

I have a bunch of other cleanups lined up for this user level daemon. If it is
ok with you, I could address this as part of that patch set. However, if 
there are more substantive changes needed in this patch-set, I will
also address this. 

Thank you,

K. Y

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

* Re: [PATCH 12/15] Tools: hv: Gather DHCP information
  2012-07-14 23:02         ` KY Srinivasan
@ 2012-07-14 23:04           ` richard -rw- weinberger
  -1 siblings, 0 replies; 45+ messages in thread
From: richard -rw- weinberger @ 2012-07-14 23:04 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw

On Sun, Jul 15, 2012 at 1:02 AM, KY Srinivasan <kys@microsoft.com> wrote:
> I have a bunch of other cleanups lined up for this user level daemon. If it is
> ok with you, I could address this as part of that patch set. However, if
> there are more substantive changes needed in this patch-set, I will
> also address this.

No problem.

-- 
Thanks,
//richard

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

* Re: [PATCH 12/15] Tools: hv: Gather DHCP information
@ 2012-07-14 23:04           ` richard -rw- weinberger
  0 siblings, 0 replies; 45+ messages in thread
From: richard -rw- weinberger @ 2012-07-14 23:04 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: olaf, gregkh, linux-kernel, virtualization, apw, devel

On Sun, Jul 15, 2012 at 1:02 AM, KY Srinivasan <kys@microsoft.com> wrote:
> I have a bunch of other cleanups lined up for this user level daemon. If it is
> ok with you, I could address this as part of that patch set. However, if
> there are more substantive changes needed in this patch-set, I will
> also address this.

No problem.

-- 
Thanks,
//richard

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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-14 20:24   ` Joe Perches
@ 2012-07-14 23:23       ` KY Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-14 23:23 UTC (permalink / raw)
  To: Joe Perches; +Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2349 bytes --]



> -----Original Message-----
> From: Joe Perches [mailto:joe@perches.com]
> Sent: Saturday, July 14, 2012 4:25 PM
> To: KY Srinivasan
> Cc: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; olaf@aepfle.de;
> apw@canonical.com
> Subject: Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
> 
> On Sat, 2012-07-14 at 13:34 -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/hv/vmbus_drv.c |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index a220e57..1f7e54a 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> >  			       device_info->chn_type.b[3],
> >  			       device_info->chn_type.b[2],
> >  			       device_info->chn_type.b[1],
> > @@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >  			       device_info->chn_type.b[15]);
> >  	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> >  			       device_info->chn_instance.b[3],
> >  			       device_info->chn_instance.b[2],
> >  			       device_info->chn_instance.b[1],
> 
> 	ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);

Thank you Joe. I recall seeing some patches from you a longtime ago on this.
I was just modifying existing code in this patch; if it is ok with you I will send a
separate patch using the preferred format string for printing GUIDS.
 
Regards,

K. Y
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
@ 2012-07-14 23:23       ` KY Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-14 23:23 UTC (permalink / raw)
  To: Joe Perches; +Cc: olaf, gregkh, linux-kernel, virtualization, apw, devel



> -----Original Message-----
> From: Joe Perches [mailto:joe@perches.com]
> Sent: Saturday, July 14, 2012 4:25 PM
> To: KY Srinivasan
> Cc: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; olaf@aepfle.de;
> apw@canonical.com
> Subject: Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
> 
> On Sat, 2012-07-14 at 13:34 -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/hv/vmbus_drv.c |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index a220e57..1f7e54a 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> >  			       device_info->chn_type.b[3],
> >  			       device_info->chn_type.b[2],
> >  			       device_info->chn_type.b[1],
> > @@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >  			       device_info->chn_type.b[15]);
> >  	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> >  			       device_info->chn_instance.b[3],
> >  			       device_info->chn_instance.b[2],
> >  			       device_info->chn_instance.b[1],
> 
> 	ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);

Thank you Joe. I recall seeing some patches from you a longtime ago on this.
I was just modifying existing code in this patch; if it is ok with you I will send a
separate patch using the preferred format string for printing GUIDS.
 
Regards,

K. Y

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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-14 23:23       ` KY Srinivasan
@ 2012-07-14 23:28         ` Joe Perches
  -1 siblings, 0 replies; 45+ messages in thread
From: Joe Perches @ 2012-07-14 23:28 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, olaf, apw

On Sat, 2012-07-14 at 23:23 +0000, KY Srinivasan wrote:
> > -----Original Message-----
> > From: Joe Perches [mailto:joe@perches.com]
> > Sent: Saturday, July 14, 2012 4:25 PM
[]
> > On Sat, 2012-07-14 at 13:34 -0700, K. Y. Srinivasan wrote:
> > > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > > tool stack easier.
[]
> > > @@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device
> > *dev,
> > >  			       device_info->chn_type.b[15]);
> > >  	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
> > >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> > >  			       device_info->chn_instance.b[3],
> > >  			       device_info->chn_instance.b[2],
> > >  			       device_info->chn_instance.b[1],
> > 
> > 	ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);
> 
> Thank you Joe. I recall seeing some patches from you a longtime ago on this.
> I was just modifying existing code in this patch; if it is ok with you I will send a
> separate patch using the preferred format string for printing GUIDS.

Hi KY.  It's your code.  Do what you think best.  cheers, Joe


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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
@ 2012-07-14 23:28         ` Joe Perches
  0 siblings, 0 replies; 45+ messages in thread
From: Joe Perches @ 2012-07-14 23:28 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: olaf, gregkh, linux-kernel, virtualization, apw, devel

On Sat, 2012-07-14 at 23:23 +0000, KY Srinivasan wrote:
> > -----Original Message-----
> > From: Joe Perches [mailto:joe@perches.com]
> > Sent: Saturday, July 14, 2012 4:25 PM
[]
> > On Sat, 2012-07-14 at 13:34 -0700, K. Y. Srinivasan wrote:
> > > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > > tool stack easier.
[]
> > > @@ -166,7 +166,7 @@ static ssize_t vmbus_show_device_attr(struct device
> > *dev,
> > >  			       device_info->chn_type.b[15]);
> > >  	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
> > >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> > >  			       device_info->chn_instance.b[3],
> > >  			       device_info->chn_instance.b[2],
> > >  			       device_info->chn_instance.b[1],
> > 
> > 	ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);
> 
> Thank you Joe. I recall seeing some patches from you a longtime ago on this.
> I was just modifying existing code in this patch; if it is ok with you I will send a
> separate patch using the preferred format string for printing GUIDS.

Hi KY.  It's your code.  Do what you think best.  cheers, Joe

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

* Re: [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection
  2012-07-14 20:34     ` K. Y. Srinivasan
  (?)
@ 2012-07-17  4:09     ` Olaf Hering
  2012-07-17 16:05       ` Greg KH
  2012-07-17 17:39       ` KY Srinivasan
  -1 siblings, 2 replies; 45+ messages in thread
From: Olaf Hering @ 2012-07-17  4:09 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: gregkh, linux-kernel, devel, apw

On Sat, Jul 14, K. Y. Srinivasan wrote:

> diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
> index 68ed7f7..38b561a 100644
> --- a/include/linux/hyperv.h
> +++ b/include/linux/hyperv.h
> @@ -127,6 +127,8 @@ enum hv_kvp_exchg_op {
>  	KVP_OP_SET,
>  	KVP_OP_DELETE,
>  	KVP_OP_ENUMERATE,
> +	KVP_OP_GET_IP_INFO,
> +	KVP_OP_SET_IP_INFO,
>  	KVP_OP_REGISTER,
>  	KVP_OP_COUNT /* Number of operations, must be last. */
>  };

I think this will break the kernel/daemon API for existing binaries.
Perhaps a forward/backwards compatible API where an older binary
continues to work with a newer kernel should be added.

Olaf

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

* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
                     ` (14 preceding siblings ...)
  2012-07-14 20:34   ` [PATCH 15/15] Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO K. Y. Srinivasan
@ 2012-07-17 16:04   ` Greg KH
  2012-07-17 16:19       ` Joe Perches
  2012-07-17 17:42       ` KY Srinivasan
  15 siblings, 2 replies; 45+ messages in thread
From: Greg KH @ 2012-07-17 16:04 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: linux-kernel, devel, virtualization, olaf, apw

On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> Format GUIDS as per MSFT standard. This makes interacting with MSFT
> tool stack easier.
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/hv/vmbus_drv.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index a220e57..1f7e54a 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
>  
>  	if (!strcmp(dev_attr->attr.name, "class_id")) {
>  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",

As Joe pointed out, please just use the printk modifier the kernel
already has for GUIDS, and don't roll your own here.  That will work
properly for you, right?

thanks,

greg k-h

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

* Re: [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection
  2012-07-17  4:09     ` Olaf Hering
@ 2012-07-17 16:05       ` Greg KH
  2012-07-17 17:39       ` KY Srinivasan
  1 sibling, 0 replies; 45+ messages in thread
From: Greg KH @ 2012-07-17 16:05 UTC (permalink / raw)
  To: Olaf Hering; +Cc: K. Y. Srinivasan, apw, linux-kernel, devel

On Tue, Jul 17, 2012 at 06:09:13AM +0200, Olaf Hering wrote:
> On Sat, Jul 14, K. Y. Srinivasan wrote:
> 
> > diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
> > index 68ed7f7..38b561a 100644
> > --- a/include/linux/hyperv.h
> > +++ b/include/linux/hyperv.h
> > @@ -127,6 +127,8 @@ enum hv_kvp_exchg_op {
> >  	KVP_OP_SET,
> >  	KVP_OP_DELETE,
> >  	KVP_OP_ENUMERATE,
> > +	KVP_OP_GET_IP_INFO,
> > +	KVP_OP_SET_IP_INFO,
> >  	KVP_OP_REGISTER,
> >  	KVP_OP_COUNT /* Number of operations, must be last. */
> >  };
> 
> I think this will break the kernel/daemon API for existing binaries.

I know it will break :)

KY, you can't break the existing user/kernel api that you created a few
kernel versions ago, sorry.  Please fix this, we can not take this
as-is, nor should you want us to.

thanks,

greg k-h

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

* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-17 16:04   ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards Greg KH
@ 2012-07-17 16:19       ` Joe Perches
  2012-07-17 17:42       ` KY Srinivasan
  1 sibling, 0 replies; 45+ messages in thread
From: Joe Perches @ 2012-07-17 16:19 UTC (permalink / raw)
  To: Greg KH; +Cc: K. Y. Srinivasan, linux-kernel, devel, virtualization, olaf, apw

On Tue, 2012-07-17 at 09:04 -0700, Greg KH wrote:
> On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
[]
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
[]
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
> >  
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> 
> As Joe pointed out, please just use the printk modifier the kernel
> already has for GUIDS, and don't roll your own here.  That will work
> properly for you, right?

%pU became available in 2.6.33

I think one of their support targets is RHEL6 which
I believe is 2.6.32+.



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

* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
@ 2012-07-17 16:19       ` Joe Perches
  0 siblings, 0 replies; 45+ messages in thread
From: Joe Perches @ 2012-07-17 16:19 UTC (permalink / raw)
  To: Greg KH; +Cc: olaf, linux-kernel, virtualization, apw, devel

On Tue, 2012-07-17 at 09:04 -0700, Greg KH wrote:
> On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
[]
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
[]
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
> >  
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> 
> As Joe pointed out, please just use the printk modifier the kernel
> already has for GUIDS, and don't roll your own here.  That will work
> properly for you, right?

%pU became available in 2.6.33

I think one of their support targets is RHEL6 which
I believe is 2.6.32+.

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

* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-17 16:19       ` Joe Perches
@ 2012-07-17 16:32         ` Greg KH
  -1 siblings, 0 replies; 45+ messages in thread
From: Greg KH @ 2012-07-17 16:32 UTC (permalink / raw)
  To: Joe Perches
  Cc: K. Y. Srinivasan, linux-kernel, devel, virtualization, olaf, apw

On Tue, Jul 17, 2012 at 09:19:26AM -0700, Joe Perches wrote:
> On Tue, 2012-07-17 at 09:04 -0700, Greg KH wrote:
> > On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > > tool stack easier.
> []
> > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> []
> > > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
> > >  
> > >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> > >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> > 
> > As Joe pointed out, please just use the printk modifier the kernel
> > already has for GUIDS, and don't roll your own here.  That will work
> > properly for you, right?
> 
> %pU became available in 2.6.33
> 
> I think one of their support targets is RHEL6 which
> I believe is 2.6.32+.

That's nice, but it's nothing that I care about for in-kernel code, nor
should anyone else.

greg k-h

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

* Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
@ 2012-07-17 16:32         ` Greg KH
  0 siblings, 0 replies; 45+ messages in thread
From: Greg KH @ 2012-07-17 16:32 UTC (permalink / raw)
  To: Joe Perches; +Cc: olaf, linux-kernel, virtualization, apw, devel

On Tue, Jul 17, 2012 at 09:19:26AM -0700, Joe Perches wrote:
> On Tue, 2012-07-17 at 09:04 -0700, Greg KH wrote:
> > On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > > tool stack easier.
> []
> > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> []
> > > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
> > >  
> > >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> > >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> > 
> > As Joe pointed out, please just use the printk modifier the kernel
> > already has for GUIDS, and don't roll your own here.  That will work
> > properly for you, right?
> 
> %pU became available in 2.6.33
> 
> I think one of their support targets is RHEL6 which
> I believe is 2.6.32+.

That's nice, but it's nothing that I care about for in-kernel code, nor
should anyone else.

greg k-h

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

* RE: [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection
  2012-07-17  4:09     ` Olaf Hering
  2012-07-17 16:05       ` Greg KH
@ 2012-07-17 17:39       ` KY Srinivasan
  1 sibling, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-17 17:39 UTC (permalink / raw)
  To: Olaf Hering; +Cc: gregkh, linux-kernel, devel, apw

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1546 bytes --]



> -----Original Message-----
> From: Olaf Hering [mailto:olaf@aepfle.de]
> Sent: Tuesday, July 17, 2012 12:09 AM
> To: KY Srinivasan
> Cc: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; apw@canonical.com
> Subject: Re: [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address
> injection
> 
> On Sat, Jul 14, K. Y. Srinivasan wrote:
> 
> > diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
> > index 68ed7f7..38b561a 100644
> > --- a/include/linux/hyperv.h
> > +++ b/include/linux/hyperv.h
> > @@ -127,6 +127,8 @@ enum hv_kvp_exchg_op {
> >  	KVP_OP_SET,
> >  	KVP_OP_DELETE,
> >  	KVP_OP_ENUMERATE,
> > +	KVP_OP_GET_IP_INFO,
> > +	KVP_OP_SET_IP_INFO,
> >  	KVP_OP_REGISTER,
> >  	KVP_OP_COUNT /* Number of operations, must be last. */
> >  };
> 
> I think this will break the kernel/daemon API for existing binaries.
> Perhaps a forward/backwards compatible API where an older binary
> continues to work with a newer kernel should be added.

You are right. If I were to keep the existing op codes unchanged, I think we can 
maintain backward compatibility - older daemon binaries will be able to function
correctly on newer KVP driver. However, newer daemon binary will require a 
matching KVP driver. Let me first validate what I think is the case. Greg, please drop
the patch-set; I will resubmit the set.

Regards,

K. Y
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
  2012-07-17 16:04   ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards Greg KH
@ 2012-07-17 17:42       ` KY Srinivasan
  2012-07-17 17:42       ` KY Srinivasan
  1 sibling, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-17 17:42 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, devel, virtualization, olaf, apw



> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Tuesday, July 17, 2012 12:04 PM
> To: KY Srinivasan
> Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> virtualization@lists.osdl.org; olaf@aepfle.de; apw@canonical.com
> Subject: Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
> 
> On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/hv/vmbus_drv.c |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index a220e57..1f7e54a 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> 
> As Joe pointed out, please just use the printk modifier the kernel
> already has for GUIDS, and don't roll your own here.  That will work
> properly for you, right?

Will do. Please drop the patch-set; I will post new patches soon.

K. Y




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

* RE: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
@ 2012-07-17 17:42       ` KY Srinivasan
  0 siblings, 0 replies; 45+ messages in thread
From: KY Srinivasan @ 2012-07-17 17:42 UTC (permalink / raw)
  To: Greg KH; +Cc: apw, devel, olaf, linux-kernel, virtualization



> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Tuesday, July 17, 2012 12:04 PM
> To: KY Srinivasan
> Cc: linux-kernel@vger.kernel.org; devel@linuxdriverproject.org;
> virtualization@lists.osdl.org; olaf@aepfle.de; apw@canonical.com
> Subject: Re: [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards
> 
> On Sat, Jul 14, 2012 at 01:34:06PM -0700, K. Y. Srinivasan wrote:
> > Format GUIDS as per MSFT standard. This makes interacting with MSFT
> > tool stack easier.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/hv/vmbus_drv.c |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index a220e57..1f7e54a 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -147,7 +147,7 @@ static ssize_t vmbus_show_device_attr(struct device
> *dev,
> >
> >  	if (!strcmp(dev_attr->attr.name, "class_id")) {
> >  		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> > -			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
> > +			       "%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
> 
> As Joe pointed out, please just use the printk modifier the kernel
> already has for GUIDS, and don't roll your own here.  That will work
> properly for you, right?

Will do. Please drop the patch-set; I will post new patches soon.

K. Y

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

end of thread, other threads:[~2012-07-17 17:44 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-14 20:32 [PATCH 00/15] drivers: hv: kvp K. Y. Srinivasan
2012-07-14 20:34 ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards K. Y. Srinivasan
2012-07-14 20:24   ` Joe Perches
2012-07-14 23:23     ` KY Srinivasan
2012-07-14 23:23       ` KY Srinivasan
2012-07-14 23:28       ` Joe Perches
2012-07-14 23:28         ` Joe Perches
2012-07-14 20:34   ` [PATCH 02/15] Drivers: hv: Add KVP definitions for IP address injection K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-17  4:09     ` Olaf Hering
2012-07-17 16:05       ` Greg KH
2012-07-17 17:39       ` KY Srinivasan
2012-07-14 20:34   ` [PATCH 03/15] Drivers: hv: kvp: Cleanup error handling in KVP K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 04/15] Drivers: hv: kvp: Support the new IP injection messages K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 05/15] Tools: hv: Prepare to expand kvp_get_ip_address() functionality K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 06/15] Tools: hv: Further refactor kvp_get_ip_address() K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 07/15] Tools: hv: Gather address family information K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 08/15] Tools: hv: Gather subnet information K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 09/15] Tools: hv: Represent the ipv6 mask using CIDR notation K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 10/15] Tools: hv: Gather ipv[4,6] gateway information K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 11/15] Tools: hv: Gather DNS information K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 12/15] Tools: hv: Gather DHCP information K. Y. Srinivasan
2012-07-14 21:36     ` richard -rw- weinberger
2012-07-14 23:02       ` KY Srinivasan
2012-07-14 23:02         ` KY Srinivasan
2012-07-14 23:04         ` richard -rw- weinberger
2012-07-14 23:04           ` richard -rw- weinberger
2012-07-14 20:34   ` [PATCH 13/15] Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO K. Y. Srinivasan
2012-07-14 20:34     ` K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 14/15] Tools: hv: Rename the function kvp_get_ip_address() K. Y. Srinivasan
2012-07-14 20:34   ` [PATCH 15/15] Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO K. Y. Srinivasan
2012-07-17 16:04   ` [PATCH 01/15] Drivers: hv: Format GUIDS as per MSFT standards Greg KH
2012-07-17 16:19     ` Joe Perches
2012-07-17 16:19       ` Joe Perches
2012-07-17 16:32       ` Greg KH
2012-07-17 16:32         ` Greg KH
2012-07-17 17:42     ` KY Srinivasan
2012-07-17 17:42       ` KY Srinivasan

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.