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,