From dba447c1eed52628c756fc2614de119d44da10f3 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 23 Feb 2017 17:58:09 -0700 Subject: [PATCH] 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 --- rmnetctl/cli/rmnetcli.c | 14 ++++++++++++- rmnetctl/inc/librmnetctl.h | 24 +++++++++++++++++++++- rmnetctl/src/librmnetctl.c | 42 +++++++++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) 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 @@ static void rmnet_api_usage(void) printf(_5TABS" must be less than"); printf(_5TABS" 15 chars. Returns"); printf(_5TABS" the status code\n\n"); + printf("rmnetcli newvndname 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 Get name of"); printf(_5TABS" network device node from id\n\n"); printf("rmnetcli freevnd Removes virtual"); @@ -311,6 +318,11 @@ static int rmnet_api_call(int argc, char *argv[]) _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 @@ int rmnet_new_vnd_prefix(rmnetctl_hndl_t *hndl, 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 @@ int rmnet_new_vnd_prefix(rmnetctl_hndl_t *hndl, 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,