aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c42
-rw-r--r--net/core/ethtool.c3
-rw-r--r--net/core/flow_dissector.c1
-rw-r--r--net/core/net-sysfs.c2
-rw-r--r--net/core/net_namespace.c31
-rw-r--r--net/core/netpoll.c2
-rw-r--r--net/core/netprio_cgroup.c15
-rw-r--r--net/core/pktgen.c4
-rw-r--r--net/core/rtnetlink.c3
-rw-r--r--net/core/secure_seq.c2
-rw-r--r--net/core/sock.c11
11 files changed, 65 insertions, 51 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index f494675471a9..6ca32f6b3105 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1887,6 +1887,23 @@ void skb_set_dev(struct sk_buff *skb, struct net_device *dev)
EXPORT_SYMBOL(skb_set_dev);
#endif /* CONFIG_NET_NS */
+static void skb_warn_bad_offload(const struct sk_buff *skb)
+{
+ static const netdev_features_t null_features = 0;
+ struct net_device *dev = skb->dev;
+ const char *driver = "";
+
+ if (dev && dev->dev.parent)
+ driver = dev_driver_string(dev->dev.parent);
+
+ WARN(1, "%s: caps=(%pNF, %pNF) len=%d data_len=%d gso_size=%d "
+ "gso_type=%d ip_summed=%d\n",
+ driver, dev ? &dev->features : &null_features,
+ skb->sk ? &skb->sk->sk_route_caps : &null_features,
+ skb->len, skb->data_len, skb_shinfo(skb)->gso_size,
+ skb_shinfo(skb)->gso_type, skb->ip_summed);
+}
+
/*
* Invalidate hardware checksum when packet is to be mangled, and
* complete checksum manually on outgoing path.
@@ -1900,8 +1917,8 @@ int skb_checksum_help(struct sk_buff *skb)
goto out_set_summed;
if (unlikely(skb_shinfo(skb)->gso_size)) {
- /* Let GSO fix up the checksum. */
- goto out_set_summed;
+ skb_warn_bad_offload(skb);
+ return -EINVAL;
}
offset = skb_checksum_start_offset(skb);
@@ -1961,16 +1978,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb,
__skb_pull(skb, skb->mac_len);
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
- struct net_device *dev = skb->dev;
- struct ethtool_drvinfo info = {};
-
- if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
- dev->ethtool_ops->get_drvinfo(dev, &info);
-
- WARN(1, "%s: caps=(%pNF, %pNF) len=%d data_len=%d ip_summed=%d\n",
- info.driver, dev ? &dev->features : NULL,
- skb->sk ? &skb->sk->sk_route_caps : NULL,
- skb->len, skb->data_len, skb->ip_summed);
+ skb_warn_bad_offload(skb);
if (skb_header_cloned(skb) &&
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
@@ -3492,14 +3500,20 @@ static inline gro_result_t
__napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
struct sk_buff *p;
+ unsigned int maclen = skb->dev->hard_header_len;
for (p = napi->gro_list; p; p = p->next) {
unsigned long diffs;
diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
diffs |= p->vlan_tci ^ skb->vlan_tci;
- diffs |= compare_ether_header(skb_mac_header(p),
- skb_gro_mac_header(skb));
+ if (maclen == ETH_HLEN)
+ diffs |= compare_ether_header(skb_mac_header(p),
+ skb_gro_mac_header(skb));
+ else if (!diffs)
+ diffs = memcmp(skb_mac_header(p),
+ skb_gro_mac_header(skb),
+ maclen);
NAPI_GRO_CB(p)->same_flow = !diffs;
NAPI_GRO_CB(p)->flush = 0;
}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 921aa2b4b415..3f79db1b612a 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1190,6 +1190,8 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
if (!dev->ethtool_ops->flash_device)
return -EOPNOTSUPP;
+ efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
+
return dev->ethtool_ops->flash_device(dev, &efl);
}
@@ -1311,6 +1313,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GRXCSUM:
case ETHTOOL_GTXCSUM:
case ETHTOOL_GSG:
+ case ETHTOOL_GSSET_INFO:
case ETHTOOL_GSTRINGS:
case ETHTOOL_GTSO:
case ETHTOOL_GPERMADDR:
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 0985b9b14b80..a225089df5b6 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1,4 +1,5 @@
#include <linux/skbuff.h>
+#include <linux/export.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index f3dbd4f596a4..a1727cda03d7 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -929,7 +929,7 @@ static ssize_t bql_show_inflight(struct netdev_queue *queue,
}
static struct netdev_queue_attribute bql_inflight_attribute =
- __ATTR(inflight, S_IRUGO | S_IWUSR, bql_show_inflight, NULL);
+ __ATTR(inflight, S_IRUGO, bql_show_inflight, NULL);
#define BQL_ATTR(NAME, FIELD) \
static ssize_t bql_show_ ## NAME(struct netdev_queue *queue, \
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index aefcd7acbffa..0e950fda9a0a 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -30,6 +30,20 @@ EXPORT_SYMBOL(init_net);
#define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */
+static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS;
+
+static struct net_generic *net_alloc_generic(void)
+{
+ struct net_generic *ng;
+ size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]);
+
+ ng = kzalloc(generic_size, GFP_KERNEL);
+ if (ng)
+ ng->len = max_gen_ptrs;
+
+ return ng;
+}
+
static int net_assign_generic(struct net *net, int id, void *data)
{
struct net_generic *ng, *old_ng;
@@ -43,8 +57,7 @@ static int net_assign_generic(struct net *net, int id, void *data)
if (old_ng->len >= id)
goto assign;
- ng = kzalloc(sizeof(struct net_generic) +
- id * sizeof(void *), GFP_KERNEL);
+ ng = net_alloc_generic();
if (ng == NULL)
return -ENOMEM;
@@ -59,7 +72,6 @@ static int net_assign_generic(struct net *net, int id, void *data)
* the old copy for kfree after a grace period.
*/
- ng->len = id;
memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
rcu_assign_pointer(net->gen, ng);
@@ -161,18 +173,6 @@ out_undo:
goto out;
}
-static struct net_generic *net_alloc_generic(void)
-{
- struct net_generic *ng;
- size_t generic_size = sizeof(struct net_generic) +
- INITIAL_NET_GEN_PTRS * sizeof(void *);
-
- ng = kzalloc(generic_size, GFP_KERNEL);
- if (ng)
- ng->len = INITIAL_NET_GEN_PTRS;
-
- return ng;
-}
#ifdef CONFIG_NET_NS
static struct kmem_cache *net_cachep;
@@ -483,6 +483,7 @@ again:
}
return error;
}
+ max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id);
}
error = __register_pernet_operations(list, ops);
if (error) {
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 556b08298669..ddefc513b44a 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -194,7 +194,7 @@ static void netpoll_poll_dev(struct net_device *dev)
poll_napi(dev);
- if (dev->priv_flags & IFF_SLAVE) {
+ if (dev->flags & IFF_SLAVE) {
if (dev->npinfo) {
struct net_device *bond_dev = dev->master;
struct sk_buff *skb;
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 3a9fd4826b75..4dacc44637ef 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -58,11 +58,12 @@ static int get_prioidx(u32 *prio)
spin_lock_irqsave(&prioidx_map_lock, flags);
prioidx = find_first_zero_bit(prioidx_map, sizeof(unsigned long) * PRIOIDX_SZ);
+ if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ) {
+ spin_unlock_irqrestore(&prioidx_map_lock, flags);
+ return -ENOSPC;
+ }
set_bit(prioidx, prioidx_map);
spin_unlock_irqrestore(&prioidx_map_lock, flags);
- if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ)
- return -ENOSPC;
-
atomic_set(&max_prioidx, prioidx);
*prio = prioidx;
return 0;
@@ -107,7 +108,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len)
static void update_netdev_tables(void)
{
struct net_device *dev;
- u32 max_len = atomic_read(&max_prioidx);
+ u32 max_len = atomic_read(&max_prioidx) + 1;
struct netprio_map *map;
rtnl_lock();
@@ -270,7 +271,6 @@ static int netprio_device_event(struct notifier_block *unused,
{
struct net_device *dev = ptr;
struct netprio_map *old;
- u32 max_len = atomic_read(&max_prioidx);
/*
* Note this is called with rtnl_lock held so we have update side
@@ -278,11 +278,6 @@ static int netprio_device_event(struct notifier_block *unused,
*/
switch (event) {
-
- case NETDEV_REGISTER:
- if (max_len)
- extend_netdev_table(dev, max_len);
- break;
case NETDEV_UNREGISTER:
old = rtnl_dereference(dev->priomap);
RCU_INIT_POINTER(dev->priomap, NULL);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 65f80c7b1656..4d8ce93cd503 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -767,8 +767,8 @@ done:
return i;
}
-static unsigned long num_arg(const char __user * user_buffer,
- unsigned long maxlen, unsigned long *num)
+static long num_arg(const char __user *user_buffer, unsigned long maxlen,
+ unsigned long *num)
{
int i;
*num = 0;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f16444bc6cbb..65aebd450027 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1509,6 +1509,9 @@ errout:
if (send_addr_notify)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+ min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev),
+ min_ifinfo_dump_size);
+
return err;
}
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index 6fd44606fdd1..99b2596531bb 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -46,7 +46,7 @@ __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + daddr[i];
+ secret[i] = net_secret[i] + (__force u32)daddr[i];
secret[4] = net_secret[4] +
(((__force u16)sport << 16) + (__force u16)dport);
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
diff --git a/net/core/sock.c b/net/core/sock.c
index 5c5af9988f94..02f8dfe320b7 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1171,13 +1171,10 @@ EXPORT_SYMBOL(sock_update_classid);
void sock_update_netprioidx(struct sock *sk)
{
- struct cgroup_netprio_state *state;
if (in_interrupt())
return;
- rcu_read_lock();
- state = task_netprio_state(current);
- sk->sk_cgrp_prioidx = state ? state->prioidx : 0;
- rcu_read_unlock();
+
+ sk->sk_cgrp_prioidx = task_netprioidx(current);
}
EXPORT_SYMBOL_GPL(sock_update_netprioidx);
#endif
@@ -1827,7 +1824,7 @@ suppress_allocation:
/* Alas. Undo changes. */
sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
- sk_memory_allocated_sub(sk, amt, parent_status);
+ sk_memory_allocated_sub(sk, amt);
return 0;
}
@@ -1840,7 +1837,7 @@ EXPORT_SYMBOL(__sk_mem_schedule);
void __sk_mem_reclaim(struct sock *sk)
{
sk_memory_allocated_sub(sk,
- sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, 0);
+ sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT);
sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
if (sk_under_memory_pressure(sk) &&