summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarout Hedeshian <harouth@codeaurora.org>2013-10-08 11:46:55 -0600
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:04:56 -0700
commit0f789efb3a122daecbb5dcf2df16f2943dd2603e (patch)
tree38ff1f84275bee8c0812e40678fca857a2ad5c27
parent5b658211916169e1c2e94daf06697705c2e4b95a (diff)
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>
-rw-r--r--include/uapi/linux/rmnet_data.h17
-rw-r--r--net/rmnet_data/rmnet_data_config.c54
-rw-r--r--net/rmnet_data/rmnet_data_config.h1
-rw-r--r--net/rmnet_data/rmnet_data_private.h2
-rw-r--r--net/rmnet_data/rmnet_data_vnd.c63
-rw-r--r--net/rmnet_data/rmnet_data_vnd.h4
6 files changed, 132 insertions, 9 deletions
diff --git a/include/uapi/linux/rmnet_data.h b/include/uapi/linux/rmnet_data.h
index b8dbf907c8b3..bcff313a95c0 100644
--- a/include/uapi/linux/rmnet_data.h
+++ b/include/uapi/linux/rmnet_data.h
@@ -165,6 +165,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
* Returns: status code
diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c
index caa6cfb516c7..e7a92696499c 100644
--- a/net/rmnet_data/rmnet_data_config.c
+++ b/net/rmnet_data/rmnet_data_config.c
@@ -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);
}
diff --git a/net/rmnet_data/rmnet_data_config.h b/net/rmnet_data/rmnet_data_config.h
index 2f8efc59f45d..2eac471fc83c 100644
--- a/net/rmnet_data/rmnet_data_config.h
+++ b/net/rmnet_data/rmnet_data_config.h
@@ -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_ */
diff --git a/net/rmnet_data/rmnet_data_private.h b/net/rmnet_data/rmnet_data_private.h
index ae253b9db5fc..cc4f2e4a27ca 100644
--- a/net/rmnet_data/rmnet_data_private.h
+++ b/net/rmnet_data/rmnet_data_private.h
@@ -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
diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c
index f304de49404d..dc59e8db55fa 100644
--- a/net/rmnet_data/rmnet_data_vnd.c
+++ b/net/rmnet_data/rmnet_data_vnd.c
@@ -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",
@@ -407,6 +423,45 @@ int rmnet_vnd_create_dev(int id, struct net_device **new_device)
}
/**
+ * 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
*
diff --git a/net/rmnet_data/rmnet_data_vnd.h b/net/rmnet_data/rmnet_data_vnd.h
index a916b2534a6d..2e1ff1c5d87b 100644
--- a/net/rmnet_data/rmnet_data_vnd.h
+++ b/net/rmnet_data/rmnet_data_vnd.h
@@ -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);