diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-08-13 10:06:51 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-16 13:48:07 -0700 |
commit | 9b5957803cb444a99275355eb2309b6fecc63c5f (patch) | |
tree | 87a9d2885d7fbce7e5ce90b7cca1b9a871f586e3 | |
parent | 07646d9c0938d40b943c592dd1c6435ab24c4e2f (diff) | |
download | lwn-9b5957803cb444a99275355eb2309b6fecc63c5f.tar.gz lwn-9b5957803cb444a99275355eb2309b6fecc63c5f.zip |
Drivers: hv: Add KVP definitions for IP address injection
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>
Reviewed-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/hv/hv_util.c | 4 | ||||
-rw-r--r-- | include/linux/hyperv.h | 76 | ||||
-rw-r--r-- | tools/hv/hv_kvp_daemon.c | 2 |
3 files changed, 77 insertions, 5 deletions
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index d3ac6a40118b..a0667de7a04c 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 68ed7f7e1fc9..11afc4e0849a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -122,12 +122,53 @@ #define REG_U32 4 #define REG_U64 8 +/* + * As we look at expanding the KVP functionality to include + * IP injection functionality, we need to maintain binary + * compatibility with older daemons. + * + * The KVP opcodes are defined by the host and it was unfortunate + * that I chose to treat the registration operation as part of the + * KVP operations defined by the host. + * Here is the level of compatibility + * (between the user level daemon and the kernel KVP driver) that we + * will implement: + * + * An older daemon will always be supported on a newer driver. + * A given user level daemon will require a minimal version of the + * kernel driver. + * If we cannot handle the version differences, we will fail gracefully + * (this can happen when we have a user level daemon that is more + * advanced than the KVP driver. + * + * We will use values used in this handshake for determining if we have + * workable user level daemon and the kernel driver. We begin by taking the + * registration opcode out of the KVP opcode namespace. We will however, + * maintain compatibility with the existing user-level daemon code. + */ + +/* + * Daemon code not supporting IP injection (legacy daemon). + */ + +#define KVP_OP_REGISTER 4 + +/* + * Daemon code supporting IP injection. + * The KVP opcode field is used to communicate the + * registration information; so define a namespace that + * will be distinct from the host defined KVP opcode. + */ + +#define KVP_OP_REGISTER1 100 + enum hv_kvp_exchg_op { KVP_OP_GET = 0, KVP_OP_SET, KVP_OP_DELETE, KVP_OP_ENUMERATE, - KVP_OP_REGISTER, + KVP_OP_GET_IP_INFO, + KVP_OP_SET_IP_INFO, KVP_OP_COUNT /* Number of operations, must be last. */ }; @@ -140,6 +181,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; @@ -181,16 +242,26 @@ struct hv_kvp_register { }; struct hv_kvp_msg { - struct hv_kvp_hdr kvp_hdr; + union { + struct hv_kvp_hdr kvp_hdr; + int error; + }; union { struct hv_kvp_msg_get kvp_get; 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 +1053,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 d9834b362943..8fbcf7b3c69d 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 = ""; |