librmnetctl: Add support to create device name as specified by user

rmnet_data assigns device name by the order they are created.
This causes problems which multiple processes are trying to
create devices and leads to random device names.

Assign device name as specified by user.

CRs-Fixed: 2018794
Change-Id: Ie0630611d658418b067df796321f4c3f565b9661
diff --git a/rmnetctl/cli/rmnetcli.c b/rmnetctl/cli/rmnetcli.c
index 2275ec2..a483c93 100644
--- a/rmnetctl/cli/rmnetcli.c
+++ b/rmnetctl/cli/rmnetcli.c
@@ -2,7 +2,7 @@
 
 			R M N E T C L I . C
 
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -187,6 +187,13 @@
 	printf(_5TABS" must be less than");
 	printf(_5TABS" 15 chars. Returns");
 	printf(_5TABS" the status code\n\n");
+	printf("rmnetcli newvndname <dev_id> <name_prefix>   Creates");
+	printf(_5TABS" virtual network device node.");
+	printf(_5TABS" dev_id is an int");
+	printf(_5TABS" less than 32. Name");
+	printf(_5TABS" must be less than");
+	printf(_5TABS" 15 chars. Returns");
+	printf(_5TABS" the status code\n\n");
 	printf("rmnetcli getvndname <dev_id>              Get name of");
 	printf(_5TABS" network device node from id\n\n");
 	printf("rmnetcli freevnd <dev_id>              Removes virtual");
@@ -311,6 +318,11 @@
 		_RMNETCLI_CHECKNULL(argv[2]);
 		return_code = rmnet_new_vnd_prefix(handle,
 		_STRTOUI32(argv[1]), &error_number, RMNETCTL_NEW_VND, argv[2]);
+	} else if (!strcmp(*argv, "newvndname")) {
+		_RMNETCLI_CHECKNULL(argv[1]);
+		_RMNETCLI_CHECKNULL(argv[2]);
+		return_code = rmnet_new_vnd_name(handle,
+		_STRTOUI32(argv[1]), &error_number, argv[2]);
 	} else if (!strcmp(*argv, "newvnd")) {
 		_RMNETCLI_CHECKNULL(argv[1]);
 		return_code = rmnet_new_vnd(handle,
diff --git a/rmnetctl/inc/librmnetctl.h b/rmnetctl/inc/librmnetctl.h
index ff78011..8913cc8 100644
--- a/rmnetctl/inc/librmnetctl.h
+++ b/rmnetctl/inc/librmnetctl.h
@@ -2,7 +2,7 @@
 
 			  L I B R M N E T C T L . H
 
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -450,6 +450,28 @@
 			 uint16_t *error_code,
 			 uint8_t new_vnd,
 			 const char *prefix);
+
+/*!
+ * @brief Public API to create a new virtual device node with a custom prefix
+ * @details Message type is RMNET_NETLINK_NEW_VND or
+ * RMNETCTL_FREE_VND based on the flag for new_vnd
+ * @param hndl RmNet handle for the Netlink message
+ * @param id Node number to create the virtual network device node
+ * @param error_code Status code of this operation returned from the kernel
+ * @param new_vnd creates a new virtual network device if  RMNETCTL_NEW_VND or
+ * frees the device if RMNETCTL_FREE_VND
+ * @param name Name to be used when naming the network interface
+ * @return RMNETCTL_SUCCESS if successful
+ * @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
+ * @return RMNETCTL_KERNEL_ERR if there was an error in the kernel.
+ * Check error_code
+ * @return RMNETCTL_INVALID_ARG if invalid arguments were passed to the API
+ */
+int rmnet_new_vnd_name(rmnetctl_hndl_t *hndl,
+			 uint32_t id,
+			 uint16_t *error_code,
+			 const char *name);
+
 /*!
  * @brief API to get the ASCII name of a virtual network device from its ID
  * @param hndl RmNet handle for the Netlink message
diff --git a/rmnetctl/src/librmnetctl.c b/rmnetctl/src/librmnetctl.c
index 95f0510..1cb9930 100644
--- a/rmnetctl/src/librmnetctl.c
+++ b/rmnetctl/src/librmnetctl.c
@@ -2,7 +2,7 @@
 
 			L I B R M N E T C T L . C
 
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -806,6 +806,46 @@
 	return return_code;
 }
 
+int rmnet_new_vnd_name(rmnetctl_hndl_t *hndl,
+			 uint32_t id,
+			 uint16_t *error_code,
+			 const char *prefix)
+{
+	struct rmnet_nl_msg_s request, response;
+	int return_code = RMNETCTL_LIB_ERR;
+	size_t str_len = 0;
+	do {
+	if ((!hndl) || (!error_code)) {
+		return_code = RMNETCTL_INVALID_ARG;
+		break;
+	}
+
+	memset(request.vnd.vnd_name, 0, RMNET_MAX_STR_LEN);
+		if (prefix) {
+			request.message_type =RMNET_NETLINK_NEW_VND_WITH_NAME;
+			str_len = strlcpy((char *)request.vnd.vnd_name,
+					  prefix, RMNET_MAX_STR_LEN);
+			if (_rmnetctl_check_len(str_len, error_code)
+						!= RMNETCTL_SUCCESS)
+				break;
+		} else {
+			request.message_type = RMNET_NETLINK_NEW_VND;
+		}
+
+	request.arg_length = sizeof(uint32_t);
+	request.vnd.id = id;
+
+	if ((*error_code = rmnetctl_transact(hndl, &request, &response))
+		!= RMNETCTL_SUCCESS)
+		break;
+	if (_rmnetctl_check_code(response.crd, error_code) != RMNETCTL_SUCCESS)
+		break;
+
+	return_code = _rmnetctl_set_codes(response.return_code, error_code);
+	} while(0);
+	return return_code;
+}
+
 int rmnet_new_vnd(rmnetctl_hndl_t *hndl,
 		  uint32_t id,
 		  uint16_t *error_code,