net: rmnet_data: Support for NETLINK getters

Added support for RMNET_NETLINK_GET_LOGICAL_EP_CONFIG
and RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED in the
rmnet_data configuration module.

CRs-fixed: 599231
Change-Id: Ib5eeb4a37f80a4df19cb3c1ef02ec477f5445740
Acked-by: David Arinzon <darinzon@qti.qualcomm.com>
Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
This commit is contained in:
Harout Hedeshian 2014-04-01 06:24:25 -06:00
parent 25cc820560
commit acba8da49f
3 changed files with 146 additions and 13 deletions

View File

@ -251,7 +251,7 @@ static void _rmnet_netlink_set_logical_ep_config
rmnet_header->local_ep_config.next_dev);
if (dev != 0 && dev2 != 0)
if (dev && dev2)
resp_rmnet->return_code =
rmnet_set_logical_endpoint_config(
dev,
@ -261,9 +261,9 @@ static void _rmnet_netlink_set_logical_ep_config
else
resp_rmnet->return_code = RMNET_CONFIG_NO_SUCH_DEVICE;
if (dev != 0)
if (dev)
dev_put(dev);
if (dev2 != 0)
if (dev2)
dev_put(dev2);
}
@ -284,7 +284,7 @@ static void _rmnet_netlink_unset_logical_ep_config
dev = dev_get_by_name(&init_net,
rmnet_header->local_ep_config.dev);
if (dev != 0) {
if (dev) {
resp_rmnet->return_code =
rmnet_unset_logical_endpoint_config(
dev,
@ -295,6 +295,44 @@ static void _rmnet_netlink_unset_logical_ep_config
}
}
static void _rmnet_netlink_get_logical_ep_config
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
if (rmnet_header->local_ep_config.ep_id < -1
|| rmnet_header->local_ep_config.ep_id > 254) {
resp_rmnet->return_code = RMNET_CONFIG_BAD_ARGUMENTS;
return;
}
dev = dev_get_by_name(&init_net,
rmnet_header->local_ep_config.dev);
if (dev)
resp_rmnet->return_code =
rmnet_get_logical_endpoint_config(
dev,
rmnet_header->local_ep_config.ep_id,
&resp_rmnet->local_ep_config.operating_mode,
resp_rmnet->local_ep_config.next_dev,
sizeof(resp_rmnet->local_ep_config.next_dev));
else {
resp_rmnet->return_code = RMNET_CONFIG_NO_SUCH_DEVICE;
return;
}
if (resp_rmnet->return_code == RMNET_CONFIG_OK) {
/* Begin Data */
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNDATA;
resp_rmnet->arg_length = RMNET_NL_MSG_SIZE(local_ep_config);
}
dev_put(dev);
}
static void _rmnet_netlink_associate_network_device
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
@ -331,6 +369,26 @@ static void _rmnet_netlink_unassociate_network_device
dev_put(dev);
}
static void _rmnet_netlink_get_network_device_associated
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
dev = dev_get_by_name(&init_net, rmnet_header->data);
if (!dev) {
resp_rmnet->return_code = RMNET_CONFIG_NO_SUCH_DEVICE;
return;
}
resp_rmnet->return_code = _rmnet_is_physical_endpoint_associated(dev);
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNDATA;
dev_put(dev);
}
static void _rmnet_netlink_get_link_egress_data_format
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
@ -509,6 +567,11 @@ void rmnet_config_netlink_msg_handler(struct sk_buff *skb)
(rmnet_header, resp_rmnet);
break;
case RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED:
_rmnet_netlink_get_network_device_associated
(rmnet_header, resp_rmnet);
break;
case RMNET_NETLINK_SET_LINK_EGRESS_DATA_FORMAT:
_rmnet_netlink_set_link_egress_data_format
(rmnet_header, resp_rmnet);
@ -538,6 +601,10 @@ void rmnet_config_netlink_msg_handler(struct sk_buff *skb)
resp_rmnet);
break;
case RMNET_NETLINK_GET_LOGICAL_EP_CONFIG:
_rmnet_netlink_get_logical_ep_config(rmnet_header, resp_rmnet);
break;
case RMNET_NETLINK_NEW_VND:
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
resp_rmnet->return_code =
@ -927,6 +994,58 @@ int rmnet_unset_logical_endpoint_config(struct net_device *dev,
return _rmnet_unset_logical_endpoint_config(dev, config_id);
}
/**
* rmnet_get_logical_endpoint_config() - Gets logical endpoing configuration
* for a device
* @dev: Device to get endpoint configuration on
* @config_id: logical endpoint id on device
* @rmnet_mode: (I/O) logical endpoint mode
* @egress_dev_name: (I/O) logical endpoint egress device name
* @egress_dev_name_size: The maximal size of the I/O egress_dev_name
*
* Retrieves the logical_endpoint_config structure.
* Network device must already have association with RmNet Data driver
*
* Return:
* - RMNET_CONFIG_OK if successful
* - RMNET_CONFIG_UNKNOWN_ERROR net_device private section is null
* - RMNET_CONFIG_NO_SUCH_DEVICE device is not associated
* - RMNET_CONFIG_BAD_ARGUMENTS if logical endpoint id is out of range or
* if the provided buffer size for egress dev name is too short
*/
int rmnet_get_logical_endpoint_config(struct net_device *dev,
int config_id,
uint8_t *rmnet_mode,
uint8_t *egress_dev_name,
size_t egress_dev_name_size)
{
struct rmnet_logical_ep_conf_s *epconfig_l = 0;
size_t strlcpy_res = 0;
LOGL("(%s, %d);", dev->name, config_id);
if (!egress_dev_name || !rmnet_mode)
return RMNET_CONFIG_BAD_ARGUMENTS;
if (config_id < RMNET_LOCAL_LOGICAL_ENDPOINT
|| config_id >= RMNET_DATA_MAX_LOGICAL_EP)
return RMNET_CONFIG_BAD_ARGUMENTS;
epconfig_l = _rmnet_get_logical_ep(dev, config_id);
if (!epconfig_l || !epconfig_l->refcount)
return RMNET_CONFIG_NO_SUCH_DEVICE;
*rmnet_mode = epconfig_l->rmnet_mode;
strlcpy_res = strlcpy(egress_dev_name, epconfig_l->egress_dev->name,
egress_dev_name_size);
if (strlcpy_res >= egress_dev_name_size)
return RMNET_CONFIG_BAD_ARGUMENTS;
return RMNET_CONFIG_OK;
}
/**
* rmnet_create_vnd() - Create virtual network device node
* @id: RmNet virtual device node id

View File

@ -69,6 +69,14 @@ int _rmnet_unset_logical_endpoint_config(struct net_device *dev,
int config_id);
int rmnet_unset_logical_endpoint_config(struct net_device *dev,
int config_id);
int _rmnet_get_logical_endpoint_config(struct net_device *dev,
int config_id,
struct rmnet_logical_ep_conf_s *epconfig);
int rmnet_get_logical_endpoint_config(struct net_device *dev,
int config_id,
uint8_t *rmnet_mode,
uint8_t *egress_dev_name,
size_t egress_dev_name_size);
void rmnet_config_netlink_msg_handler (struct sk_buff *skb);
int rmnet_config_notify_cb(struct notifier_block *nb,
unsigned long event, void *data);

View File

@ -541,10 +541,10 @@ int rmnet_vnd_init(void)
*
* Return:
* - 0 if successful
* - -EINVAL if id is out of range, or id already in use
* - -EINVAL if net_device allocation failed
* - -EINVAL if prefix does not fit in buffer
* - return code of register_netdevice() on other errors
* - RMNET_CONFIG_BAD_ARGUMENTS if id is out of range or prefix is too long
* - RMNET_CONFIG_DEVICE_IN_USE if id already in use
* - RMNET_CONFIG_NOMEM if net_device allocation failed
* - RMNET_CONFIG_UNKNOWN_ERROR if register_netdevice() fails
*/
int rmnet_vnd_create_dev(int id, struct net_device **new_device,
const char *prefix)
@ -553,9 +553,14 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
char dev_prefix[IFNAMSIZ];
int p, rc = 0;
if (id < 0 || id >= RMNET_DATA_MAX_VND || rmnet_devices[id] != 0) {
if (id < 0 || id > RMNET_DATA_MAX_VND) {
*new_device = 0;
return -EINVAL;
return RMNET_CONFIG_BAD_ARGUMENTS;
}
if (rmnet_devices[id] != 0) {
*new_device = 0;
return RMNET_CONFIG_DEVICE_IN_USE;
}
if (!prefix)
@ -565,8 +570,8 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
p = scnprintf(dev_prefix, IFNAMSIZ, "%s%%d",
prefix);
if (p >= (IFNAMSIZ-1)) {
LOGE("Specified prefix (%d) longer than IFNAMSIZ", p);
return -EINVAL;
LOGE("Specified prefix longer than IFNAMSIZ");
return RMNET_CONFIG_BAD_ARGUMENTS;
}
dev = alloc_netdev(sizeof(struct rmnet_vnd_private_s),
@ -575,7 +580,7 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
if (!dev) {
LOGE("Failed to to allocate netdev for id %d", id);
*new_device = 0;
return -EINVAL;
return RMNET_CONFIG_NOMEM;
}
rc = register_netdevice(dev);
@ -583,6 +588,7 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device,
LOGE("Failed to to register netdev [%s]", dev->name);
free_netdev(dev);
*new_device = 0;
return RMNET_CONFIG_UNKNOWN_ERROR;
} else {
rmnet_devices[id] = dev;
*new_device = dev;