summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/rtnetlink.c18
-rw-r--r--net/rmnet_data/rmnet_data_config.c47
-rw-r--r--net/rmnet_data/rmnet_data_config.h6
-rw-r--r--net/rmnet_data/rmnet_data_handlers.c19
-rw-r--r--net/rmnet_data/rmnet_data_stats.c15
-rw-r--r--net/rmnet_data/rmnet_map.h9
-rw-r--r--net/rmnet_data/rmnet_map_command.c7
-rw-r--r--net/rmnet_data/rmnet_map_data.c9
8 files changed, 82 insertions, 48 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index ca966f7de351..87b91ffbdec3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1175,14 +1175,16 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
{
- struct rtnl_link_ifmap map = {
- .mem_start = dev->mem_start,
- .mem_end = dev->mem_end,
- .base_addr = dev->base_addr,
- .irq = dev->irq,
- .dma = dev->dma,
- .port = dev->if_port,
- };
+ struct rtnl_link_ifmap map;
+
+ memset(&map, 0, sizeof(map));
+ map.mem_start = dev->mem_start;
+ map.mem_end = dev->mem_end;
+ map.base_addr = dev->base_addr;
+ map.irq = dev->irq;
+ map.dma = dev->dma;
+ map.port = dev->if_port;
+
if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
return -EMSGSIZE;
diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c
index c49393924e26..ebce455b645d 100644
--- a/net/rmnet_data/rmnet_data_config.c
+++ b/net/rmnet_data/rmnet_data_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/rmnet_data.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_data_handlers.h"
#include "rmnet_data_vnd.h"
@@ -141,14 +142,22 @@ static inline int _rmnet_is_physical_endpoint_associated(struct net_device *dev)
* - pointer to configuration if successful
* - 0 (null) if device is not associated
*/
-static inline struct rmnet_phys_ep_conf_s *_rmnet_get_phys_ep_config
- (struct net_device *dev)
+struct rmnet_phys_ep_config *_rmnet_get_phys_ep_config
+ (struct net_device *dev)
{
- if (_rmnet_is_physical_endpoint_associated(dev))
- return (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(dev->rx_handler_data);
- else
+ struct rmnet_phys_ep_conf_s *_rmnet_phys_ep_config;
+
+ if (_rmnet_is_physical_endpoint_associated(dev)) {
+ _rmnet_phys_ep_config = (struct rmnet_phys_ep_conf_s *)
+ rcu_dereference(dev->rx_handler_data);
+ if (_rmnet_phys_ep_config && _rmnet_phys_ep_config->config)
+ return (struct rmnet_phys_ep_config *)
+ _rmnet_phys_ep_config->config;
+ else
+ return 0;
+ } else {
return 0;
+ }
}
/**
@@ -165,7 +174,7 @@ static inline struct rmnet_phys_ep_conf_s *_rmnet_get_phys_ep_config
struct rmnet_logical_ep_conf_s *_rmnet_get_logical_ep(struct net_device *dev,
int config_id)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct rmnet_logical_ep_conf_s *epconfig_l;
if (rmnet_vnd_is_vnd(dev))
@@ -400,7 +409,7 @@ static void _rmnet_netlink_get_link_egress_data_format
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
@@ -432,7 +441,7 @@ static void _rmnet_netlink_get_link_ingress_data_format
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
@@ -725,7 +734,7 @@ int rmnet_set_ingress_data_format(struct net_device *dev,
uint32_t ingress_data_format,
uint8_t tail_spacing)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
ASSERT_RTNL();
LOGL("(%s,0x%08X);", dev->name, ingress_data_format);
@@ -762,7 +771,7 @@ int rmnet_set_egress_data_format(struct net_device *dev,
uint16_t agg_size,
uint16_t agg_count)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
ASSERT_RTNL();
LOGL("(%s,0x%08X, %d, %d);",
@@ -800,7 +809,9 @@ int rmnet_set_egress_data_format(struct net_device *dev,
int rmnet_associate_network_device(struct net_device *dev)
{
struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *conf;
int rc;
+
ASSERT_RTNL();
LOGL("(%s);\n", dev->name);
@@ -819,19 +830,25 @@ int rmnet_associate_network_device(struct net_device *dev)
}
config = kmalloc(sizeof(*config), GFP_ATOMIC);
+ conf = kmalloc(sizeof(*conf), GFP_ATOMIC);
- if (!config)
+ if (!config || !conf)
return RMNET_CONFIG_NOMEM;
memset(config, 0, sizeof(struct rmnet_phys_ep_conf_s));
- config->dev = dev;
- spin_lock_init(&config->agg_lock);
+ memset(conf, 0, sizeof(struct rmnet_phys_ep_config));
+
+ config->config = conf;
+ conf->dev = dev;
+ spin_lock_init(&conf->agg_lock);
+ config->recycle = kfree_skb;
rc = netdev_rx_handler_register(dev, rmnet_rx_handler, config);
if (rc) {
LOGM("netdev_rx_handler_register returns %d", rc);
kfree(config);
+ kfree(conf);
return RMNET_CONFIG_DEVICE_IN_USE;
}
diff --git a/net/rmnet_data/rmnet_data_config.h b/net/rmnet_data/rmnet_data_config.h
index a76bcef79e6a..78329c38b364 100644
--- a/net/rmnet_data/rmnet_data_config.h
+++ b/net/rmnet_data/rmnet_data_config.h
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/time.h>
#include <linux/spinlock.h>
+#include <net/rmnet_config.h>
#ifndef _RMNET_DATA_CONFIG_H_
#define _RMNET_DATA_CONFIG_H_
@@ -62,7 +63,7 @@ struct rmnet_logical_ep_conf_s {
* @agg_time: Wall clock time when aggregated frame was created
* @agg_last: Last time the aggregation routing was invoked
*/
-struct rmnet_phys_ep_conf_s {
+struct rmnet_phys_ep_config {
struct net_device *dev;
struct rmnet_logical_ep_conf_s local_ep;
struct rmnet_logical_ep_conf_s muxed_ep[RMNET_DATA_MAX_LOGICAL_EP];
@@ -123,4 +124,7 @@ int rmnet_create_vnd(int id);
int rmnet_create_vnd_prefix(int id, const char *name);
int rmnet_free_vnd(int id);
+struct rmnet_phys_ep_config *_rmnet_get_phys_ep_config
+ (struct net_device *dev);
+
#endif /* _RMNET_DATA_CONFIG_H_ */
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index 9d04b2f8ddd9..185b609e637f 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -22,6 +22,7 @@
#include <linux/netdev_features.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_private.h"
#include "rmnet_data_config.h"
#include "rmnet_data_vnd.h"
@@ -321,7 +322,7 @@ static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,
* - RX_HANDLER_PASS if packet should be passed up the stack by caller
*/
static rx_handler_result_t rmnet_ingress_deliver_packet(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
if (!config) {
LOGD("%s", "NULL physical EP provided");
@@ -356,7 +357,7 @@ static rx_handler_result_t rmnet_ingress_deliver_packet(struct sk_buff *skb,
* - result of __rmnet_deliver_skb() for all other cases
*/
static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_logical_ep_conf_s *ep;
uint8_t mux_id;
@@ -440,7 +441,7 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
* - result of _rmnet_map_ingress_handler() for all other cases
*/
static rx_handler_result_t rmnet_map_ingress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct sk_buff *skbn;
int rc, co = 0;
@@ -480,7 +481,7 @@ static rx_handler_result_t rmnet_map_ingress_handler(struct sk_buff *skb,
* - 1 on failure
*/
static int rmnet_map_egress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config,
+ struct rmnet_phys_ep_config *config,
struct rmnet_logical_ep_conf_s *ep,
struct net_device *orig_dev)
{
@@ -563,7 +564,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
*/
rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct net_device *dev;
int rc;
@@ -574,8 +575,7 @@ rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
trace_rmnet_ingress_handler(skb);
rmnet_print_packet(skb, dev->name, 'r');
- config = (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(skb->dev->rx_handler_data);
+ config = _rmnet_get_phys_ep_config(skb->dev);
if (!config) {
LOGD("%s is not associated with rmnet_data", skb->dev->name);
@@ -654,14 +654,13 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
void rmnet_egress_handler(struct sk_buff *skb,
struct rmnet_logical_ep_conf_s *ep)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct net_device *orig_dev;
int rc;
orig_dev = skb->dev;
skb->dev = ep->egress_dev;
- config = (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(skb->dev->rx_handler_data);
+ config = _rmnet_get_phys_ep_config(skb->dev);
if (!config) {
LOGD("%s is not associated with rmnet_data", skb->dev->name);
diff --git a/net/rmnet_data/rmnet_data_stats.c b/net/rmnet_data/rmnet_data_stats.c
index 5fefda55c72c..20f1628242c7 100644
--- a/net/rmnet_data/rmnet_data_stats.c
+++ b/net/rmnet_data/rmnet_data_stats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_private.h"
#include "rmnet_data_stats.h"
#include "rmnet_data_config.h"
@@ -73,8 +74,16 @@ void rmnet_kfree_skb(struct sk_buff *skb, unsigned int reason)
skb_free[reason]++;
spin_unlock_irqrestore(&rmnet_skb_free_lock, flags);
- if (skb)
- kfree_skb(skb);
+ if (likely(skb)) {
+ struct rmnet_phys_ep_conf_s *config;
+
+ config = (struct rmnet_phys_ep_conf_s *)rcu_dereference
+ (skb->dev->rx_handler_data);
+ if (likely(config))
+ config->recycle(skb);
+ else
+ kfree_skb(skb);
+ }
}
void rmnet_stats_queue_xmit(int rc, unsigned int reason)
diff --git a/net/rmnet_data/rmnet_map.h b/net/rmnet_data/rmnet_map.h
index 0a6ad908b827..71abca122dd6 100644
--- a/net/rmnet_data/rmnet_map.h
+++ b/net/rmnet_data/rmnet_map.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <net/rmnet_config.h>
#ifndef _RMNET_MAP_H_
#define _RMNET_MAP_H_
@@ -133,14 +134,14 @@ enum rmnet_map_agg_state_e {
uint8_t rmnet_map_demultiplex(struct sk_buff *skb);
struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb,
int hdrlen, int pad);
rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
void rmnet_map_aggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
int rmnet_map_checksum_downlink_packet(struct sk_buff *skb);
int rmnet_map_checksum_uplink_packet(struct sk_buff *skb,
diff --git a/net/rmnet_data/rmnet_map_command.c b/net/rmnet_data/rmnet_map_command.c
index 4bcfa10db486..055d5f402957 100644
--- a/net/rmnet_data/rmnet_map_command.c
+++ b/net/rmnet_data/rmnet_map_command.c
@@ -18,6 +18,7 @@
#include <linux/rmnet_data.h>
#include <linux/net_map.h>
#include <net/pkt_sched.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_map.h"
#include "rmnet_data_private.h"
@@ -44,7 +45,7 @@ MODULE_PARM_DESC(rmnet_map_command_stats, "MAP command statistics");
* - RMNET_MAP_COMMAND_ACK on success
*/
static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config,
+ struct rmnet_phys_ep_config *config,
int enable)
{
struct rmnet_map_control_command_s *cmd;
@@ -116,7 +117,7 @@ static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb,
*/
static void rmnet_map_send_ack(struct sk_buff *skb,
unsigned char type,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_map_control_command_s *cmd;
int xmit_status;
@@ -162,7 +163,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
* - RX_HANDLER_CONSUMED. Command frames are always consumed.
*/
rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_map_control_command_s *cmd;
unsigned char command_name;
diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c
index 68caf44c1f92..beff8332c731 100644
--- a/net/rmnet_data/rmnet_map_data.c
+++ b/net/rmnet_data/rmnet_map_data.c
@@ -31,6 +31,7 @@
#include <net/ip.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_map.h"
#include "rmnet_data_private.h"
@@ -52,7 +53,7 @@ MODULE_PARM_DESC(agg_bypass_time, "Skip agg when apart spaced more than this");
struct agg_work {
struct delayed_work work;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
};
#define RMNET_MAP_DEAGGR_SPACING 64
@@ -131,7 +132,7 @@ done:
* - 0 (null) if no more aggregated packets
*/
struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct sk_buff *skbn;
struct rmnet_map_header_s *maph;
@@ -185,7 +186,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
static void rmnet_map_flush_packet_queue(struct work_struct *work)
{
struct agg_work *real_work;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
unsigned long flags;
struct sk_buff *skb;
int rc, agg_count = 0;
@@ -233,7 +234,7 @@ static void rmnet_map_flush_packet_queue(struct work_struct *work)
* the argument SKB and should not be further processed by any other function.
*/
void rmnet_map_aggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config) {
+ struct rmnet_phys_ep_config *config) {
uint8_t *dest_buff;
struct agg_work *work;
unsigned long flags;