net: rmnet_data: Add support for user defined device name prefix

Run-time user space components can now specify virtual network device
name prefix at device creation. This will be used to support legacy
data services.

CRs-Fixed: 555507
Change-Id: Id34c2761f2060e66b05c521304d5151620ba5665
Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
This commit is contained in:
Harout Hedeshian 2013-10-08 11:46:55 -06:00
parent 099576a663
commit bc0019b052
6 changed files with 132 additions and 9 deletions

View File

@ -164,6 +164,23 @@ enum rmnet_netlink_message_types_e {
*/
RMNET_NETLINK_NEW_VND,
/*
* RMNET_NETLINK_NEW_VND_WITH_PREFIX - Creates a new virtual network
* device node with the specified
* prefix for the device name
* Args: int32_t node number
* char[] vnd_name - Use as prefix
* Returns: status code
*/
RMNET_NETLINK_NEW_VND_WITH_PREFIX,
/*
* RMNET_NETLINK_GET_VND_NAME - Gets the string name of a VND from ID
* Args: int32_t node number
* Returns: char[] vnd_name
*/
RMNET_NETLINK_GET_VND_NAME,
/*
* RMNET_NETLINK_FREE_VND - Removes virtual network device node
* Args: int32_t node number

View File

@ -237,7 +237,7 @@ static void _rmnet_netlink_unassociate_network_device
resp_rmnet->return_code = rmnet_unassociate_network_device(dev);
}
static inline void _rmnet_netlink_get_link_egress_data_format
static void _rmnet_netlink_get_link_egress_data_format
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
{
@ -267,7 +267,7 @@ static inline void _rmnet_netlink_get_link_egress_data_format
resp_rmnet->data_format.agg_size = config->egress_agg_size;
}
static inline void _rmnet_netlink_get_link_ingress_data_format
static void _rmnet_netlink_get_link_ingress_data_format
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
{
@ -295,6 +295,27 @@ static inline void _rmnet_netlink_get_link_ingress_data_format
resp_rmnet->data_format.flags = config->ingress_data_format;
}
static void _rmnet_netlink_get_vnd_name
(struct rmnet_nl_msg_s *rmnet_header,
struct rmnet_nl_msg_s *resp_rmnet)
{
int r;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
r = rmnet_vnd_get_name(rmnet_header->vnd.id, resp_rmnet->vnd.vnd_name,
RMNET_MAX_STR_LEN);
if (r != 0) {
resp_rmnet->return_code = RMNET_CONFIG_INVALID_REQUEST;
return;
}
/* Begin Data */
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNDATA;
resp_rmnet->arg_length = RMNET_NL_MSG_SIZE(vnd);
}
/**
* rmnet_config_netlink_msg_handler() - Netlink message handler callback
* @skb: Packet containing netlink messages
@ -386,6 +407,17 @@ void rmnet_config_netlink_msg_handler(struct sk_buff *skb)
rmnet_create_vnd(rmnet_header->vnd.id);
break;
case RMNET_NETLINK_NEW_VND_WITH_PREFIX:
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
resp_rmnet->return_code = rmnet_create_vnd_prefix(
rmnet_header->vnd.id,
rmnet_header->vnd.vnd_name);
break;
case RMNET_NETLINK_GET_VND_NAME:
_rmnet_netlink_get_vnd_name(rmnet_header, resp_rmnet);
break;
default:
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
resp_rmnet->return_code = RMNET_CONFIG_UNKNOWN_MESSAGE;
@ -669,5 +701,21 @@ int rmnet_create_vnd(int id)
struct net_device *dev;
ASSERT_RTNL();
LOGL("%s(%d);", __func__, id);
return rmnet_vnd_create_dev(id, &dev);
return rmnet_vnd_create_dev(id, &dev, NULL);
}
/**
* rmnet_create_vnd() - Create virtual network device node
* @id: RmNet virtual device node id
* @prefix: String prefix for device name
*
* Return:
* - result of rmnet_vnd_create_dev()
*/
int rmnet_create_vnd_prefix(int id, const char *prefix)
{
struct net_device *dev;
ASSERT_RTNL();
LOGL("%s(%d, \"%s\");", __func__, id, prefix);
return rmnet_vnd_create_dev(id, &dev, prefix);
}

View File

@ -65,5 +65,6 @@ int rmnet_set_logical_endpoint_config(struct net_device *dev,
struct net_device *egress_dev);
void rmnet_config_netlink_msg_handler (struct sk_buff *skb);
int rmnet_create_vnd(int id);
int rmnet_create_vnd_prefix(int id, const char *name);
#endif /* _RMNET_DATA_CONFIG_H_ */

View File

@ -17,7 +17,7 @@
#define RMNET_DATA_MAX_VND 32
#define RMNET_DATA_MAX_PACKET_SIZE 16384
#define RMNET_DATA_DFLT_PACKET_SIZE 1500
#define RMNET_DATA_DEV_NAME_STR "rmnet_data%d"
#define RMNET_DATA_DEV_NAME_STR "rmnet_data"
#define RMNET_DATA_NEEDED_HEADROOM 16
#define RMNET_ETHERNET_HEADER_LENGTH 14

View File

@ -360,29 +360,45 @@ int rmnet_vnd_init(void)
* rmnet_vnd_create_dev() - Create a new virtual network device node.
* @id: Virtual device node id
* @new_device: Pointer to newly created device node
* @prefix: Device name prefix
*
* Allocates structures for new virtual network devices. Sets the name of the
* new device and registers it with the network stack. Device will appear in
* ifconfig list after this is called.
* ifconfig list after this is called. If the prefix is null, then
* RMNET_DATA_DEV_NAME_STR will be assumed.
*
* 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
*/
int rmnet_vnd_create_dev(int id, struct net_device **new_device)
int rmnet_vnd_create_dev(int id, struct net_device **new_device,
const char *prefix)
{
struct net_device *dev;
int rc = 0;
char dev_prefix[IFNAMSIZ];
int p, rc = 0;
if (id < 0 || id > RMNET_DATA_MAX_VND || rmnet_devices[id] != 0) {
*new_device = 0;
return -EINVAL;
}
if (!prefix)
p = scnprintf(dev_prefix, IFNAMSIZ, "%s%%d",
RMNET_DATA_DEV_NAME_STR);
else
p = scnprintf(dev_prefix, IFNAMSIZ, "%s%%d",
prefix);
if (p >= (IFNAMSIZ-1)) {
LOGE("%s(): Specified prefix longer than IFNAMSIZ", __func__);
return -EINVAL;
}
dev = alloc_netdev(sizeof(struct rmnet_vnd_private_s),
RMNET_DATA_DEV_NAME_STR,
dev_prefix,
rmnet_vnd_setup);
if (!dev) {
LOGE("%s(): Failed to to allocate netdev for id %d",
@ -406,6 +422,45 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device)
return rc;
}
/**
* rmnet_vnd_get_name() - Gets the string name of a VND based on ID
* @id: Virtual device node id
* @name: Buffer to store name of virtual device node
* @name_len: Length of name buffer
*
* Copies the name of the virtual device node into the users buffer. Will throw
* an error if the buffer is null, or too small to hold the device name.
*
* Return:
* - 0 if successful
* - -EINVAL if name is null
* - -EINVAL if id is invalid or not in range
* - -EINVAL if name is too small to hold things
*/
int rmnet_vnd_get_name(int id, char *name, int name_len)
{
int p;
if (!name) {
LOGM("%s(): Bad arguments; name buffer null", __func__);
return -EINVAL;
}
if ((id < 0) || (id >= RMNET_DATA_MAX_VND) || !rmnet_devices[id]) {
LOGM("%s(): Invalid id [%d]", __func__, id);
return -EINVAL;
}
p = strlcpy(name, rmnet_devices[id]->name, name_len);
if (p >= name_len) {
LOGM("%s(): Buffer to small to fit device name", __func__);
return -EINVAL;
}
LOGL("%s(): Found mapping [%d]->\"%s\"", __func__, id, name);
return 0;
}
/**
* rmnet_vnd_is_vnd() - Determine if net_device is RmNet owned virtual devices
* @dev: Network device to test

View File

@ -23,7 +23,9 @@ int rmnet_vnd_get_flow_mapping(struct net_device *dev,
unsigned int map_flow_id,
unsigned int *flow_map);
struct rmnet_logical_ep_conf_s *rmnet_vnd_get_le_config(struct net_device *dev);
int rmnet_vnd_create_dev(int id, struct net_device **new_device);
int rmnet_vnd_get_name(int id, char *name, int name_len);
int rmnet_vnd_create_dev(int id, struct net_device **new_device,
const char *prefix);
int rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev);
int rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev);
int rmnet_vnd_is_vnd(struct net_device *dev);