[PATCH 13/13] Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Implement the KVP_OP_SET_IP_INFO verb. This operation sets the IP information
on the specified interface.

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

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 569f4d7..8eefdb5 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -847,6 +847,183 @@ getaddr_done:
 	return error;
 }
 
+int parse_ip_val_buffer(char *in_buf, int *offset, char *out_buf, int out_len)
+{
+	int end;
+	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_path[256];
+	char if_tmp_path[256];
+	FILE *file;
+	char addr[INET6_ADDRSTRLEN];
+	int i;
+	char cmd[256];
+	char str[256];
+	int offset;
+
+	/*
+	 * Set the specified info in the appropriate config file
+	 * for the specified interface and flush the settings.
+	 * Currently we support distributions that maintain
+	 * network configuration information in file:
+	 * /etc/sysconfig/network-scripts/icfg-ifname
+	 */
+	memset(if_path, 0, sizeof(if_path));
+	strcat(if_path, "/etc/sysconfig/network-scripts/ifcfg-");
+	strcat(if_path, if_name);
+
+	memset(if_tmp_path, 0, sizeof(if_tmp_path));
+	strcat(if_tmp_path, "/var/opt/hyperv/.kvp_ifcfg-");
+	strcat(if_tmp_path, if_name);
+
+	file = fopen(if_path, "r");
+	if (file == NULL) {
+		/*
+		 * This system maintains the interface configuration
+		 * information in a different location. Need to add
+		 * code to deal with that. For now fail the operation.
+		 */
+		return 1;
+	}
+
+	fclose(file);
+	/*
+	 * The host gives us complete configuration information for the
+	 * interface; just overwrite the current info.
+	 * To deal with intermediate failues, first write a temp file.
+	 */
+
+	file = fopen(if_tmp_path, "w");
+
+	if (file == NULL)
+		return 1;
+
+	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))) {
+		sprintf(str, "IPADDR_%d=", i++);
+		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))) {
+		sprintf(str, "NETMAK_%d=", i++);
+		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))) {
+		sprintf(str, "GATEWAY_%d=", i++);
+		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->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;
+	}
+
+	error = fputs("ONBOOT=yes\n", file);
+	if (error == EOF)
+		goto setval_error;
+
+	error = fputs("PEERDNS=yes\n", file);
+	if (error == EOF)
+		goto setval_error;
+
+setval_done:
+	/*
+	 * Now move the config file to the final location.
+	 */
+	fclose(file);
+	memset(cmd, 0, sizeof(cmd));
+	strcat(cmd, "mv ");
+	strcat(cmd, if_tmp_path);
+	strcat(cmd, "  ");
+	strcat(cmd, if_path);
+	system(cmd);
+
+	/*
+	 * Now restart the network to flush the parameters.
+	 */
+	memset(cmd, 0, sizeof(cmd));
+	strcat(cmd, "service network restart");
+	system(cmd);
+	return 0;
+
+setval_error:
+	fclose(file);
+	return error;
+}
 
 static int
 kvp_get_domain_name(char *buffer, int length)
@@ -1048,6 +1225,27 @@ int main(void)
 			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(
+						(char *)kvp_ip_val->adapter_id,
+						MAX_ADAPTER_ID_SIZE);
+			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(hv_msg->kvp_hdr.pool,
 					hv_msg->body.kvp_set.data.key,
-- 
1.7.4.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux