lkml.org 
[lkml]   [2012]   [Aug]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V2 04/18] Drivers: hv: kvp: Support the new IP injection messages
    Date
    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>
    Reviewed-by: Olaf Hering <olaf@aepfle.de>
    Reviewed-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/hv/hv_kvp.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++--
    1 files changed, 137 insertions(+), 6 deletions(-)

    diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
    index eb4d073..810f176 100644
    --- a/drivers/hv/hv_kvp.c
    +++ b/drivers/hv/hv_kvp.c
    @@ -63,7 +63,7 @@ static int dm_reg_value;
    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(int);

    @@ -108,7 +108,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);
    }

    static int kvp_handle_handshake(struct hv_kvp_msg *msg)
    @@ -199,9 +199,120 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
    * 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
    kvp_send_key(struct work_struct *dummy)
    {
    @@ -237,6 +348,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:
    @@ -313,17 +430,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.
    @@ -376,6 +495,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;
    @@ -389,7 +518,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
    @@ -403,6 +532,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);
    @@ -455,7 +585,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


    \
     
     \ /
      Last update: 2012-08-13 19:45    [W:3.769 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site