Skip to content
Snippets Groups Projects
Commit 77825571 authored by Harout Hedeshian's avatar Harout Hedeshian
Browse files

rmnetctl: Enhancements and bug fixes

This patch introduced a new variable (string len) for
rmnet_get_logical_ep_config as well as a new set of error
values which match the errors produced by rmnet_data.
Additionally, several fixes such as a memory leak and input
checks were applied.

CRs-Fixed: 599231
Change-Id: Ia662b4393d7de0bb1629fb7d3b45bc7c109a9866
parent 22b96bca
No related branches found
No related tags found
No related merge requests found
......@@ -203,7 +203,8 @@ static void rmnet_api_usage(void)
printf(_2TABS" device node\n\n");
}
static void print_rmnetctl_lib_errors(uint16_t error_number) {
static void print_rmnetctl_lib_errors(uint16_t error_number)
{
if ((error_number > RMNETCTL_API_SUCCESS) &&
(error_number < RMNETCTL_API_ERR_ENUM_LENGTH)) {
printf("%s", rmnetctl_error_code_text[error_number]);
......@@ -228,16 +229,13 @@ static void print_rmnet_api_status(int return_code, uint16_t error_number)
{
if (return_code == RMNETCTL_SUCCESS)
printf("SUCCESS\n");
else if (return_code == RMNETCTL_LIB_ERR)
else if (return_code == RMNETCTL_LIB_ERR) {
printf("LIBRARY ");
else if (return_code == RMNETCTL_KERNEL_ERR)
printf("KERNEL : Error code %u\n", error_number);
print_rmnetctl_lib_errors(error_number);
} else if (return_code == RMNETCTL_KERNEL_ERR)
printf("KERNEL %s", rmnetctl_error_code_text[error_number]);
else if (return_code == RMNETCTL_INVALID_ARG)
printf("INVALID_ARG\n");
if (return_code == RMNETCTL_LIB_ERR) {
print_rmnetctl_lib_errors(error_number);
}
}
/*!
......@@ -358,7 +356,7 @@ static int rmnet_api_call(int argc, char *argv[])
}
return_code = rmnet_get_logical_ep_config(handle,
_STRTOI32(argv[1]), argv[2], &rmnet_mode,
&egress_dev_name, &error_number);
&egress_dev_name, RMNET_MAX_STR_LEN, &error_number);
if (return_code == RMNETCTL_SUCCESS) {
printf("rmnet_mode is %u\n", rmnet_mode);
printf("egress_dev_name is %s\n", egress_dev_name);
......
......@@ -66,9 +66,11 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum rmnetctl_error_codes_e {
/* API succeeded. This should always be the first element. */
RMNETCTL_API_SUCCESS,
RMNETCTL_API_FIRST_ERR,
/* API failed because not enough memory to create buffer to send
* message */
RMNETCTL_API_ERR_REQUEST_INVALID,
RMNETCTL_API_ERR_REQUEST_INVALID = RMNETCTL_API_FIRST_ERR,
/* API failed because not enough memory to create buffer for the
* response message */
RMNETCTL_API_ERR_RESPONSE_INVALID,
......@@ -76,16 +78,20 @@ enum rmnetctl_error_codes_e {
RMNETCTL_API_ERR_MESSAGE_SEND,
/* API failed because could not receive message from the kernel */
RMNETCTL_API_ERR_MESSAGE_RECEIVE,
RMNETCTL_INIT_FIRST_ERR,
/* Invalid process id. So return an error. */
RMNETCTL_INIT_ERR_PROCESS_ID,
RMNETCTL_INIT_ERR_PROCESS_ID = RMNETCTL_INIT_FIRST_ERR,
/* Invalid socket descriptor id. So return an error. */
RMNETCTL_INIT_ERR_NETLINK_FD,
/* Could not bind the socket to the Netlink file descriptor */
RMNETCTL_INIT_ERR_BIND,
/* Invalid user id. Only root has access to this function. (NA) */
RMNETCTL_INIT_ERR_INVALID_USER,
RMNETCTL_API_SECOND_ERR,
/* API failed because the RmNet handle for the transaction was NULL */
RMNETCTL_API_ERR_HNDL_INVALID,
RMNETCTL_API_ERR_HNDL_INVALID = RMNETCTL_API_SECOND_ERR,
/* API failed because the request buffer for the transaction was NULL */
RMNETCTL_API_ERR_REQUEST_NULL,
/* API failed because the response buffer for the transaction was NULL*/
......@@ -96,6 +102,33 @@ enum rmnetctl_error_codes_e {
RMNETCTL_API_ERR_RETURN_TYPE,
/* API failed because the string was truncated */
RMNETCTL_API_ERR_STRING_TRUNCATION,
/* These error are 1-to-1 with rmnet_data config errors in rmnet_data.h
for each conversion.
please keep the enums synced.
*/
RMNETCTL_KERNEL_FIRST_ERR,
/* No error */
RMNETCTL_KERNEL_ERROR_NO_ERR = RMNETCTL_KERNEL_FIRST_ERR,
/* Invalid / unsupported message */
RMNETCTL_KERNEL_ERR_UNKNOWN_MESSAGE,
/* Internal problem in the kernel modeule */
RMNETCTL_KERNEL_ERR_INTERNAL,
/* Kernel is temporarely out of memory */
RMNETCTL_KERNEL_ERR_OUT_OF_MEM,
/* Device already exists / Still in use */
RMETNCTL_KERNEL_ERR_DEVICE_IN_USE,
/* Invalid request / Unsupported scenario */
RMNETCTL_KERNEL_ERR_INVALID_REQUEST,
/* Device doesn't exist */
RMNETCTL_KERNEL_ERR_NO_SUCH_DEVICE,
/* One or more of the arguments is invalid */
RMNETCTL_KERNEL_ERR_BAD_ARGS,
/* Egress device is invalid */
RMNETCTL_KERNEL_ERR_BAD_EGRESS_DEVICE,
/* TC handle is full */
RMNETCTL_KERNEL_ERR_TC_HANDLE_FULL,
/* This should always be the last element */
RMNETCTL_API_ERR_ENUM_LENGTH
};
......@@ -121,7 +154,18 @@ char rmnetctl_error_code_text
"ERROR: Response buffer for the transaction was NULL\n",
"ERROR: Request and response type do not match\n",
"ERROR: Return type is invalid\n",
"ERROR: String was truncated\n"
"ERROR: String was truncated\n",
/* Kernel errors */
"ERROR: Kernel call succeeded\n",
"ERROR: Invalid / Unsupported directive\n",
"ERROR: Internal problem in the kernel module\n",
"ERROR: The kernel is temporarely out of memory\n",
"ERROR: Device already exists / Still in use\n",
"ERROR: Invalid request / Unsupported scenario\n",
"ERROR: Device doesn't exist\n",
"ERROR: One or more of the arguments is invalid\n",
"ERROR: Egress device is invalid\n",
"ERROR: TC handle is full\n"
};
/*===========================================================================
......@@ -348,7 +392,8 @@ int rmnet_unset_logical_ep_config(rmnetctl_hndl_t *hndl,
* @param logical_ep_id Logical end point id from which to get the configuration
* @param dev_name Device on which to get the logical end point configuration
* @param rmnet_mode RmNet mode from the device
* @param egress_dev_name Egress Device if operating in bridge mode
* @param next_dev Egress Device name
* @param next_dev_len Egress Device I/O string len
* @param error_code Status code of this operation returned from the kernel
* @return RMNETCTL_SUCCESS if successful
* @return RMNETCTL_LIB_ERR if there was a library error. Check error_code
......@@ -361,6 +406,7 @@ int rmnet_get_logical_ep_config(rmnetctl_hndl_t *hndl,
const char *dev_name,
uint8_t *operating_mode,
char **next_dev,
uint32_t next_dev_len,
uint16_t *error_code);
/*!
......
......@@ -63,7 +63,17 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define KERNEL_PROCESS_ID 0
#define UNICAST 0
#define MAX_BUF_SIZE sizeof(struct nlmsghdr) + sizeof(struct rmnet_nl_msg_s)
#define INGRESS_FLAGS_MASK (RMNET_INGRESS_FIX_ETHERNET | \
RMNET_INGRESS_FORMAT_MAP | \
RMNET_INGRESS_FORMAT_DEAGGREGATION | \
RMNET_INGRESS_FORMAT_DEMUXING | \
RMNET_INGRESS_FORMAT_MAP_COMMANDS)
#define EGRESS_FLAGS_MASK (RMNET_EGRESS_FORMAT__RESERVED__ | \
RMNET_EGRESS_FORMAT_MAP | \
RMNET_EGRESS_FORMAT_AGGREGATION | \
RMNET_EGRESS_FORMAT_MUXING)
#define min(a, b) (((a) < (b)) ? (a) : (b))
/*===========================================================================
LOCAL FUNCTION DEFINITIONS
===========================================================================*/
......@@ -183,6 +193,8 @@ static int rmnetctl_transact(rmnetctl_hndl_t *hndl,
}
return_code = RMNETCTL_SUCCESS;
} while(0);
free(request_buf);
free(response_buf);
return return_code;
}
......@@ -279,9 +291,10 @@ static inline int _rmnetctl_check_data(int crd, uint16_t *error_code) {
*/
static inline int _rmnetctl_set_codes(int error_val, uint16_t *error_code) {
int return_code = RMNETCTL_KERNEL_ERR;
*error_code = error_val;
if (*error_code == RMNETCTL_SUCCESS)
if (error_val == RMNET_CONFIG_OK)
return_code = RMNETCTL_SUCCESS;
else
*error_code = error_val + RMNETCTL_KERNEL_FIRST_ERR;
return return_code;
}
......@@ -432,7 +445,8 @@ int rmnet_set_link_egress_data_format(rmnetctl_hndl_t *hndl,
struct rmnet_nl_msg_s request, response;
int str_len = -1, return_code = RMNETCTL_LIB_ERR;
do {
if ((!hndl) || (!error_code) || _rmnetctl_check_dev_name(dev_name)) {
if ((!hndl) || (!error_code) || _rmnetctl_check_dev_name(dev_name) ||
((~EGRESS_FLAGS_MASK) & egress_flags)) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......@@ -509,7 +523,8 @@ int rmnet_set_link_ingress_data_format_tailspace(rmnetctl_hndl_t *hndl,
struct rmnet_nl_msg_s request, response;
int str_len = -1, return_code = RMNETCTL_LIB_ERR;
do {
if ((!hndl) || (!error_code) || _rmnetctl_check_dev_name(dev_name)) {
if ((!hndl) || (!error_code) || _rmnetctl_check_dev_name(dev_name) ||
((~INGRESS_FLAGS_MASK) & ingress_flags)) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......@@ -590,7 +605,8 @@ int rmnet_set_logical_ep_config(rmnetctl_hndl_t *hndl,
do {
if ((!hndl) || ((ep_id < -1) || (ep_id > 31)) || (!error_code) ||
_rmnetctl_check_dev_name(dev_name) ||
_rmnetctl_check_dev_name(next_dev)) {
_rmnetctl_check_dev_name(next_dev) ||
operating_mode >= RMNET_EPMODE_LENGTH) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......@@ -667,12 +683,14 @@ int rmnet_get_logical_ep_config(rmnetctl_hndl_t *hndl,
const char *dev_name,
uint8_t *operating_mode,
char **next_dev,
uint32_t next_dev_len,
uint16_t *error_code) {
struct rmnet_nl_msg_s request, response;
int str_len = -1, return_code = RMNETCTL_LIB_ERR;
do {
if ((!hndl) || (!operating_mode) || (!error_code) || ((ep_id < -1) ||
(ep_id > 31)) || _rmnetctl_check_dev_name(dev_name) || (!next_dev)) {
(ep_id > 31)) || _rmnetctl_check_dev_name(dev_name) || (!next_dev)
|| (0 == next_dev_len)) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......@@ -693,10 +711,10 @@ int rmnet_get_logical_ep_config(rmnetctl_hndl_t *hndl,
break;
if (_rmnetctl_check_data(response.crd, error_code) != RMNETCTL_SUCCESS)
break;
printf("%s\n", (char *)(response.local_ep_config.next_dev));
str_len = strlcpy(*next_dev,
(char *)(response.local_ep_config.next_dev),
RMNET_MAX_STR_LEN);
min(RMNET_MAX_STR_LEN, next_dev_len));
if (_rmnetctl_check_len(str_len, error_code) != RMNETCTL_SUCCESS)
break;
......@@ -770,7 +788,7 @@ int rmnet_get_vnd_name(rmnetctl_hndl_t *hndl,
uint32_t str_len;
int return_code = RMNETCTL_LIB_ERR;
do {
if ((!hndl) || (!error_code)) {
if ((!hndl) || (!error_code) || (!buf) || (0 == buflen)) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......@@ -808,8 +826,8 @@ int rmnet_add_del_vnd_tc_flow(rmnetctl_hndl_t *hndl,
struct rmnet_nl_msg_s request, response;
int return_code = RMNETCTL_LIB_ERR;
do {
if ((!hndl) || ((set_flow != RMNETCTL_ADD_FLOW) &&
(set_flow != RMNETCTL_DEL_FLOW))) {
if ((!hndl) || (!error_code) || ((set_flow != RMNETCTL_ADD_FLOW) &&
(set_flow != RMNETCTL_DEL_FLOW))) {
return_code = RMNETCTL_INVALID_ARG;
break;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment