Received: by 2002:ab2:710b:0:b0:1ef:a325:1205 with SMTP id z11csp1028771lql; Tue, 12 Mar 2024 05:38:47 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVnQX6qv1zYEIMD+k2nyTqynCCL1cgb3mjZm8ycSIEVHMBhBOyvbR6NyPgMCIMTdhgP1bVEwbpTvfRpoAoWKiay75xlNXnoQCaZbiGK2w== X-Google-Smtp-Source: AGHT+IHA0fni5f1NFIzVN9hMTiwRnE9ff1P8i0NCiQAmAX3NSSOP7zTnglAOX8sKxsscUZwU4mFl X-Received: by 2002:a17:903:1103:b0:1dc:fc84:198 with SMTP id n3-20020a170903110300b001dcfc840198mr10938031plh.29.1710247127285; Tue, 12 Mar 2024 05:38:47 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710247127; cv=pass; d=google.com; s=arc-20160816; b=Cdpy+uqW878TD1pphX0SDcv/xdAA0DvYdWgBCCyiRP+UYlHwqU/DlArljZWlfyI2iL f2cvRFXv2OxOeNG44wNzRJo6Eq4PGMgr4kMPBDGhu6fqSgP5KqsbKHeimu2sjLOv0Vnp oJ3vVVw4spQ4Ihmz0Td0daUYcmDx7rxmbEInjAyOVp/s8z1b5gCXCWxoyhKC0p3jtmQq 0zM8KM8ay/tzzRlAmDrhO8MxwZ6uQE8wmuKu4Rh+XS/1VD4DbxhI9Jlx/2TAbVJS5T40 NAYXaK06X96970ZIV9ek2PiSXnlSOfqpK2k0+B0rhaamXLRHrKhNYcln+/bjLy1tn4f6 /tzQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-id:precedence:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=sDwJ3xsCeoh5Z54rGko8eW0A7PXt+rXt9R3ZVFeOvpw=; fh=iXBWNo/x7fXCTckWZW3UImGBmcfh6deDAsZmCDLWSy8=; b=r+bWyAhvuvKMueIopf87Umy30bSWfwomkyYNb5NMbLTdr8WOiwTMvB2lQDO8OWVT6i yAkwjPJYNcyr1m23eQW3axxaJ/1OO1+orzdNQC7LISEpwRFT4GC/FrXFvHss9ckzHwlE PcB0mVekWQQlEAt2rNeq+l4Fa8wzMEd9jxkaVRjwdVss/8UOUbIEyjErF1NPLvVngjlK WyuJz5afy1RmRhkujyO/reDSE9Tsicg62a12exDYGERCu0B74N1t+AOARMcmmVhhgDdI Zm57v0pgvxYDbAN7XJL8Ba7s0rY2DyLQSDwQFtIg0MNGOb7BafyuV+5ET5oC0lSkmyCG p52g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=RNnWbBup; arc=pass (i=1 spf=pass spfdomain=linux.microsoft.com dkim=pass dkdomain=linux.microsoft.com dmarc=pass fromdomain=linux.microsoft.com); spf=pass (google.com: domain of linux-kernel+bounces-100266-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-100266-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id w9-20020a170902e88900b001dd6adda7absi6230721plg.313.2024.03.12.05.38.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 05:38:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-100266-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=RNnWbBup; arc=pass (i=1 spf=pass spfdomain=linux.microsoft.com dkim=pass dkdomain=linux.microsoft.com dmarc=pass fromdomain=linux.microsoft.com); spf=pass (google.com: domain of linux-kernel+bounces-100266-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-100266-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id EA0A528126A for ; Tue, 12 Mar 2024 12:38:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 11CD91EA95; Tue, 12 Mar 2024 12:38:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="RNnWbBup" Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6C2B47A15E; Tue, 12 Mar 2024 12:38:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710247121; cv=none; b=J0ci8FuBq/sZhI7Jrw328JyoNNVLZOtKblUNPQEbpMv0yKbQTjZQZW+r1oDGJxqtgdgF+ChmUdHRlC+QYqNXJkZx/f11r4gsAcF+lIlNsalJrFFkB45j+5AVQIDgtJP71B1PZmBeVGlUV+g0u2SRaFwh7szSyhDdZdfZVP6EVso= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710247121; c=relaxed/simple; bh=GkAYNH3txNSYtyzxuiX102WxRl42aZ7qyZWzRykfmMA=; h=From:To:Cc:Subject:Date:Message-Id; b=TmVPrFjFfaRmkp9XuyqT8UrnKoEUyZhn1utKZofQ20mbj9Jqf+bBfFfqP4BA5u93K0f75Dvky1ydTfHN/s57ByDnGHWzUV4+r8UuEnV9lY2PeEXKhigrKTjxTFw+r2IHu8ccjMeDPftHycPcTzl+PsU4wJEoqnqhyHES73xQP0s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=RNnWbBup; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Received: by linux.microsoft.com (Postfix, from userid 1134) id 7982120B74C0; Tue, 12 Mar 2024 05:38:33 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7982120B74C0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1710247113; bh=sDwJ3xsCeoh5Z54rGko8eW0A7PXt+rXt9R3ZVFeOvpw=; h=From:To:Cc:Subject:Date:From; b=RNnWbBupf2BCZ+CJUxFMW57gwfOevD24X/oS1pfxuVT+2ekyDVb2L/wkBwdKLabSQ RUiyuGDykqTp0721U0UItp8w59yvH75J8wTEBmlbHODwYBygwH1WRR2uAUIlvsa6py nHrnVoWqO9bghKvLnqe8w3u8DSTwrITOC2chpcPg= From: Shradha Gupta To: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org Cc: Shradha Gupta , "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Dexuan Cui , Long Li , Michael Kelley , Olaf Hering , Ani Sinha , Shradha Gupta Subject: [PATCH v2] hv/hv_kvp_daemon: Handle IPv4 and Ipv6 combination for keyfile format Date: Tue, 12 Mar 2024 05:38:32 -0700 Message-Id: <1710247112-7414-1-git-send-email-shradhagupta@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: If the network configuration strings are passed as a combination of IPv and IPv6 addresses, the current KVP daemon doesnot handle it for the keyfile configuration format. With these changes, the keyfile config generation logic scans through the list twice to generate IPv4 and IPv6 sections for the configuration files to handle this support. Built-on: Rhel9 Tested-on: Rhel9(IPv4 only, IPv6 only, IPv4 and IPv6 combination) Signed-off-by: Shradha Gupta --- Changes in v2 * Use calloc to avoid initialization later * Return standard error codes * Free the output_str pointer on completion * Add out-of bound checks while writing to buffers --- tools/hv/hv_kvp_daemon.c | 173 +++++++++++++++++++++++++++++---------- 1 file changed, 132 insertions(+), 41 deletions(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 318e2dad27e0..ae65be004eb1 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -76,6 +76,12 @@ enum { DNS }; +enum { + IPV4 = 1, + IPV6, + IP_TYPE_MAX +}; + static int in_hand_shake; static char *os_name = ""; @@ -102,6 +108,7 @@ static struct utsname uts_buf; #define MAX_FILE_NAME 100 #define ENTRIES_PER_BLOCK 50 +#define MAX_IP_ENTRIES 64 struct kvp_record { char key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; @@ -1171,6 +1178,18 @@ static int process_ip_string(FILE *f, char *ip_string, int type) return 0; } +int ip_version_check(const char *input_addr) +{ + struct in6_addr addr; + + if (inet_pton(AF_INET, input_addr, &addr)) + return IPV4; + else if (inet_pton(AF_INET6, input_addr, &addr)) + return IPV6; + else + return -EINVAL; +} + /* * Only IPv4 subnet strings needs to be converted to plen * For IPv6 the subnet is already privided in plen format @@ -1197,14 +1216,71 @@ static int kvp_subnet_to_plen(char *subnet_addr_str) return plen; } +static int process_dns_gateway_nm(FILE *f, char *ip_string, int type, + int ip_sec) +{ + char addr[INET6_ADDRSTRLEN], *output_str; + int ip_offset = 0, error = 0, ip_ver; + char *param_name; + + output_str = (char *)calloc(INET6_ADDRSTRLEN * MAX_IP_ENTRIES, + sizeof(char)); + + if (!output_str) + return -ENOMEM; + + memset(addr, 0, sizeof(addr)); + + if (type == DNS) { + param_name = "dns"; + } else if (type == GATEWAY) { + param_name = "gateway"; + } else { + error = -EINVAL; + goto cleanup; + } + + while (parse_ip_val_buffer(ip_string, &ip_offset, addr, + (MAX_IP_ADDR_SIZE * 2))) { + ip_ver = ip_version_check(addr); + if (ip_ver < 0) + continue; + + if ((ip_ver == IPV4 && ip_sec == IPV4) || + (ip_ver == IPV6 && ip_sec == IPV6)) { + if (((INET6_ADDRSTRLEN * MAX_IP_ENTRIES) - strlen(output_str)) > + (strlen(addr))) { + strcat(output_str, addr); + strcat(output_str, ","); + } + memset(addr, 0, sizeof(addr)); + + } else { + memset(addr, 0, sizeof(addr)); + continue; + } + } + + if (strlen(output_str)) { + output_str[strlen(output_str) - 1] = '\0'; + error = fprintf(f, "%s=%s\n", param_name, output_str); + if (error < 0) + goto cleanup; + } + +cleanup: + free(output_str); + return error; +} + static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet, - int is_ipv6) + int ip_sec) { char addr[INET6_ADDRSTRLEN]; char subnet_addr[INET6_ADDRSTRLEN]; int error, i = 0; int ip_offset = 0, subnet_offset = 0; - int plen; + int plen, ip_ver; memset(addr, 0, sizeof(addr)); memset(subnet_addr, 0, sizeof(subnet_addr)); @@ -1216,10 +1292,16 @@ static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet, subnet_addr, (MAX_IP_ADDR_SIZE * 2))) { - if (!is_ipv6) + ip_ver = ip_version_check(addr); + if (ip_ver < 0) + continue; + + if (ip_ver == IPV4 && ip_sec == IPV4) plen = kvp_subnet_to_plen((char *)subnet_addr); - else + else if (ip_ver == IPV6 && ip_sec == IPV6) plen = atoi(subnet_addr); + else + continue; if (plen < 0) return plen; @@ -1238,12 +1320,11 @@ static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet, static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val) { - int error = 0; + int error = 0, ip_type; char if_filename[PATH_MAX]; char nm_filename[PATH_MAX]; FILE *ifcfg_file, *nmfile; char cmd[PATH_MAX]; - int is_ipv6 = 0; char *mac_addr; int str_len; @@ -1421,52 +1502,62 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val) if (error) goto setval_error; - if (new_val->addr_family & ADDR_FAMILY_IPV6) { - error = fprintf(nmfile, "\n[ipv6]\n"); - if (error < 0) - goto setval_error; - is_ipv6 = 1; - } else { - error = fprintf(nmfile, "\n[ipv4]\n"); - if (error < 0) - goto setval_error; - } - /* - * Now we populate the keyfile format + * The keyfile format expects the IPv6 and IPv4 configuration in + * different sections. Therefore we iterate through the list twice, + * once to populate the IPv4 section and the next time for IPv6 */ + ip_type = IPV4; + do { + if (ip_type == IPV4) { + error = fprintf(nmfile, "\n[ipv4]\n"); + if (error < 0) + goto setval_error; + } else { + error = fprintf(nmfile, "\n[ipv6]\n"); + if (error < 0) + goto setval_error; + } - if (new_val->dhcp_enabled) { - error = kvp_write_file(nmfile, "method", "", "auto"); - if (error < 0) - goto setval_error; - } else { - error = kvp_write_file(nmfile, "method", "", "manual"); + /* + * Now we populate the keyfile format + */ + + if (new_val->dhcp_enabled) { + error = kvp_write_file(nmfile, "method", "", "auto"); + if (error < 0) + goto setval_error; + } else { + error = kvp_write_file(nmfile, "method", "", "manual"); + if (error < 0) + goto setval_error; + } + + /* + * Write the configuration for ipaddress, netmask, gateway and + * name services + */ + error = process_ip_string_nm(nmfile, (char *)new_val->ip_addr, + (char *)new_val->sub_net, + ip_type); if (error < 0) goto setval_error; - } - /* - * Write the configuration for ipaddress, netmask, gateway and - * name services - */ - error = process_ip_string_nm(nmfile, (char *)new_val->ip_addr, - (char *)new_val->sub_net, is_ipv6); - if (error < 0) - goto setval_error; - - /* we do not want ipv4 addresses in ipv6 section and vice versa */ - if (is_ipv6 != is_ipv4((char *)new_val->gate_way)) { - error = fprintf(nmfile, "gateway=%s\n", (char *)new_val->gate_way); + error = process_dns_gateway_nm(nmfile, + (char *)new_val->gate_way, + GATEWAY, ip_type); if (error < 0) goto setval_error; - } - if (is_ipv6 != is_ipv4((char *)new_val->dns_addr)) { - error = fprintf(nmfile, "dns=%s\n", (char *)new_val->dns_addr); + error = process_dns_gateway_nm(nmfile, + (char *)new_val->dns_addr, DNS, + ip_type); if (error < 0) goto setval_error; - } + + ip_type++; + } while (ip_type < IP_TYPE_MAX); + fclose(nmfile); fclose(ifcfg_file); -- 2.34.1