works for kernel-4.2.3
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86_64 4.2.2 Kernel Configuration
|
||||
# Linux/x86_64 4.2.3 Kernel Configuration
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_X86_64=y
|
||||
|
||||
Binary file not shown.
+64
@@ -0,0 +1,64 @@
|
||||
From 143081a13f31bcf05cb5685f628b6fda65d05237 Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Sat, 15 Aug 2015 13:36:12 -0500
|
||||
Subject: [PATCH 1/2] dcache: Handle escaped paths in prepend_path
|
||||
|
||||
commit cde93be45a8a90d8c264c776fab63487b5038a65 upstream.
|
||||
|
||||
A rename can result in a dentry that by walking up d_parent
|
||||
will never reach it's mnt_root. For lack of a better term
|
||||
I call this an escaped path.
|
||||
|
||||
prepend_path is called by four different functions __d_path,
|
||||
d_absolute_path, d_path, and getcwd.
|
||||
|
||||
__d_path only wants to see paths are connected to the root it passes
|
||||
in. So __d_path needs prepend_path to return an error.
|
||||
|
||||
d_absolute_path similarly wants to see paths that are connected to
|
||||
some root. Escaped paths are not connected to any mnt_root so
|
||||
d_absolute_path needs prepend_path to return an error greater
|
||||
than 1. So escaped paths will be treated like paths on lazily
|
||||
unmounted mounts.
|
||||
|
||||
getcwd needs to prepend "(unreachable)" so getcwd also needs
|
||||
prepend_path to return an error.
|
||||
|
||||
d_path is the interesting hold out. d_path just wants to print
|
||||
something, and does not care about the weird cases. Which raises
|
||||
the question what should be printed?
|
||||
|
||||
Given that <escaped_path>/<anything> should result in -ENOENT I
|
||||
believe it is desirable for escaped paths to be printed as empty
|
||||
paths. As there are not really any meaninful path components when
|
||||
considered from the perspective of a mount tree.
|
||||
|
||||
So tweak prepend_path to return an empty path with an new error
|
||||
code of 3 when it encounters an escaped path.
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
---
|
||||
fs/dcache.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/fs/dcache.c b/fs/dcache.c
|
||||
index 9b5fe503f6cb..e3b44ca75a1b 100644
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -2926,6 +2926,13 @@ restart:
|
||||
|
||||
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
|
||||
struct mount *parent = ACCESS_ONCE(mnt->mnt_parent);
|
||||
+ /* Escaped? */
|
||||
+ if (dentry != vfsmnt->mnt_root) {
|
||||
+ bptr = *buffer;
|
||||
+ blen = *buflen;
|
||||
+ error = 3;
|
||||
+ break;
|
||||
+ }
|
||||
/* Global root? */
|
||||
if (mnt != parent) {
|
||||
dentry = ACCESS_ONCE(mnt->mnt_mountpoint);
|
||||
--
|
||||
2.2.1
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
From 701cf206d76af24fc948b3a798c4ee6b7f149910 Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Sat, 15 Aug 2015 20:27:13 -0500
|
||||
Subject: [PATCH 2/2] vfs: Test for and handle paths that are unreachable from
|
||||
their mnt_root
|
||||
|
||||
commit 397d425dc26da728396e66d392d5dcb8dac30c37 upstream.
|
||||
|
||||
In rare cases a directory can be renamed out from under a bind mount.
|
||||
In those cases without special handling it becomes possible to walk up
|
||||
the directory tree to the root dentry of the filesystem and down
|
||||
from the root dentry to every other file or directory on the filesystem.
|
||||
|
||||
Like division by zero .. from an unconnected path can not be given
|
||||
a useful semantic as there is no predicting at which path component
|
||||
the code will realize it is unconnected. We certainly can not match
|
||||
the current behavior as the current behavior is a security hole.
|
||||
|
||||
Therefore when encounting .. when following an unconnected path
|
||||
return -ENOENT.
|
||||
|
||||
- Add a function path_connected to verify path->dentry is reachable
|
||||
from path->mnt.mnt_root. AKA to validate that rename did not do
|
||||
something nasty to the bind mount.
|
||||
|
||||
To avoid races path_connected must be called after following a path
|
||||
component to it's next path component.
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
---
|
||||
fs/namei.c | 27 +++++++++++++++++++++++++--
|
||||
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 1c2105ed20c5..29b927938b8c 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -560,6 +560,24 @@ static int __nd_alloc_stack(struct nameidata *nd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
|
||||
+ * @path: nameidate to verify
|
||||
+ *
|
||||
+ * Rename can sometimes move a file or directory outside of a bind
|
||||
+ * mount, path_connected allows those cases to be detected.
|
||||
+ */
|
||||
+static bool path_connected(const struct path *path)
|
||||
+{
|
||||
+ struct vfsmount *mnt = path->mnt;
|
||||
+
|
||||
+ /* Only bind mounts can have disconnected paths */
|
||||
+ if (mnt->mnt_root == mnt->mnt_sb->s_root)
|
||||
+ return true;
|
||||
+
|
||||
+ return is_subdir(path->dentry, mnt->mnt_root);
|
||||
+}
|
||||
+
|
||||
static inline int nd_alloc_stack(struct nameidata *nd)
|
||||
{
|
||||
if (likely(nd->depth != EMBEDDED_LEVELS))
|
||||
@@ -1296,6 +1314,8 @@ static int follow_dotdot_rcu(struct nameidata *nd)
|
||||
return -ECHILD;
|
||||
nd->path.dentry = parent;
|
||||
nd->seq = seq;
|
||||
+ if (unlikely(!path_connected(&nd->path)))
|
||||
+ return -ENOENT;
|
||||
break;
|
||||
} else {
|
||||
struct mount *mnt = real_mount(nd->path.mnt);
|
||||
@@ -1396,7 +1416,7 @@ static void follow_mount(struct path *path)
|
||||
}
|
||||
}
|
||||
|
||||
-static void follow_dotdot(struct nameidata *nd)
|
||||
+static int follow_dotdot(struct nameidata *nd)
|
||||
{
|
||||
if (!nd->root.mnt)
|
||||
set_root(nd);
|
||||
@@ -1412,6 +1432,8 @@ static void follow_dotdot(struct nameidata *nd)
|
||||
/* rare case of legitimate dget_parent()... */
|
||||
nd->path.dentry = dget_parent(nd->path.dentry);
|
||||
dput(old);
|
||||
+ if (unlikely(!path_connected(&nd->path)))
|
||||
+ return -ENOENT;
|
||||
break;
|
||||
}
|
||||
if (!follow_up(&nd->path))
|
||||
@@ -1419,6 +1441,7 @@ static void follow_dotdot(struct nameidata *nd)
|
||||
}
|
||||
follow_mount(&nd->path);
|
||||
nd->inode = nd->path.dentry->d_inode;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1634,7 +1657,7 @@ static inline int handle_dots(struct nameidata *nd, int type)
|
||||
if (nd->flags & LOOKUP_RCU) {
|
||||
return follow_dotdot_rcu(nd);
|
||||
} else
|
||||
- follow_dotdot(nd);
|
||||
+ return follow_dotdot(nd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.2.1
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From 18e1db67e93ed75d9dc0d34c8d783ccf10547c2b Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Thaler <bernhard.thaler@wvnet.at>
|
||||
Date: Thu, 13 Aug 2015 08:58:15 +0200
|
||||
Subject: [PATCH] netfilter: bridge: fix IPv6 packets not being bridged with
|
||||
CONFIG_IPV6=n
|
||||
|
||||
230ac490f7fba introduced a dependency to CONFIG_IPV6 which breaks bridging
|
||||
of IPv6 packets on a bridge with CONFIG_IPV6=n.
|
||||
|
||||
Sysctl entry /proc/sys/net/bridge/bridge-nf-call-ip6tables defaults to 1,
|
||||
for this reason packets are handled by br_nf_pre_routing_ipv6(). When compiled
|
||||
with CONFIG_IPV6=n this function returns NF_DROP but should return NF_ACCEPT
|
||||
to let packets through.
|
||||
|
||||
Change CONFIG_IPV6=n br_nf_pre_routing_ipv6() return value to NF_ACCEPT.
|
||||
|
||||
Tested with a simple bridge with two interfaces and IPv6 packets trying
|
||||
to pass from host on left side to host on right side of the bridge.
|
||||
|
||||
Fixes: 230ac490f7fba ("netfilter: bridge: split ipv6 code into separated file")
|
||||
Signed-off-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
include/net/netfilter/br_netfilter.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h
|
||||
index bab824b..d4c6b5f 100644
|
||||
--- a/include/net/netfilter/br_netfilter.h
|
||||
+++ b/include/net/netfilter/br_netfilter.h
|
||||
@@ -59,7 +59,7 @@ static inline unsigned int
|
||||
br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
- return NF_DROP;
|
||||
+ return NF_ACCEPT;
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
From 9cf94eab8b309e8bcc78b41dd1561c75b537dd0b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Date: Mon, 31 Aug 2015 19:11:02 +0200
|
||||
Subject: [PATCH] netfilter: conntrack: use nf_ct_tmpl_free in CT/synproxy
|
||||
error paths
|
||||
|
||||
Commit 0838aa7fcfcd ("netfilter: fix netns dependencies with conntrack
|
||||
templates") migrated templates to the new allocator api, but forgot to
|
||||
update error paths for them in CT and synproxy to use nf_ct_tmpl_free()
|
||||
instead of nf_conntrack_free().
|
||||
|
||||
Due to that, memory is being freed into the wrong kmemcache, but also
|
||||
we drop the per net reference count of ct objects causing an imbalance.
|
||||
|
||||
In Brad's case, this leads to a wrap-around of net->ct.count and thus
|
||||
lets __nf_conntrack_alloc() refuse to create a new ct object:
|
||||
|
||||
[ 10.340913] xt_addrtype: ipv6 does not support BROADCAST matching
|
||||
[ 10.810168] nf_conntrack: table full, dropping packet
|
||||
[ 11.917416] r8169 0000:07:00.0 eth0: link up
|
||||
[ 11.917438] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
|
||||
[ 12.815902] nf_conntrack: table full, dropping packet
|
||||
[ 15.688561] nf_conntrack: table full, dropping packet
|
||||
[ 15.689365] nf_conntrack: table full, dropping packet
|
||||
[ 15.690169] nf_conntrack: table full, dropping packet
|
||||
[ 15.690967] nf_conntrack: table full, dropping packet
|
||||
[...]
|
||||
|
||||
With slab debugging, it also reports the wrong kmemcache (kmalloc-512 vs.
|
||||
nf_conntrack_ffffffff81ce75c0) and reports poison overwrites, etc. Thus,
|
||||
to fix the problem, export and use nf_ct_tmpl_free() instead.
|
||||
|
||||
Fixes: 0838aa7fcfcd ("netfilter: fix netns dependencies with conntrack templates")
|
||||
Reported-by: Brad Jackson <bjackson0971@gmail.com>
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
include/net/netfilter/nf_conntrack.h | 1 +
|
||||
net/netfilter/nf_conntrack_core.c | 3 ++-
|
||||
net/netfilter/nf_synproxy_core.c | 2 +-
|
||||
net/netfilter/xt_CT.c | 2 +-
|
||||
4 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
|
||||
index 37cd391..4023c4c 100644
|
||||
--- a/include/net/netfilter/nf_conntrack.h
|
||||
+++ b/include/net/netfilter/nf_conntrack.h
|
||||
@@ -292,6 +292,7 @@ extern unsigned int nf_conntrack_hash_rnd;
|
||||
void init_nf_conntrack_hash_rnd(void);
|
||||
|
||||
struct nf_conn *nf_ct_tmpl_alloc(struct net *net, u16 zone, gfp_t flags);
|
||||
+void nf_ct_tmpl_free(struct nf_conn *tmpl);
|
||||
|
||||
#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
|
||||
#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
|
||||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
|
||||
index 3c20d02..0625a42 100644
|
||||
--- a/net/netfilter/nf_conntrack_core.c
|
||||
+++ b/net/netfilter/nf_conntrack_core.c
|
||||
@@ -320,12 +320,13 @@ out_free:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc);
|
||||
|
||||
-static void nf_ct_tmpl_free(struct nf_conn *tmpl)
|
||||
+void nf_ct_tmpl_free(struct nf_conn *tmpl)
|
||||
{
|
||||
nf_ct_ext_destroy(tmpl);
|
||||
nf_ct_ext_free(tmpl);
|
||||
kfree(tmpl);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(nf_ct_tmpl_free);
|
||||
|
||||
static void
|
||||
destroy_conntrack(struct nf_conntrack *nfct)
|
||||
diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
|
||||
index d7f1685..d6ee8f8 100644
|
||||
--- a/net/netfilter/nf_synproxy_core.c
|
||||
+++ b/net/netfilter/nf_synproxy_core.c
|
||||
@@ -378,7 +378,7 @@ static int __net_init synproxy_net_init(struct net *net)
|
||||
err3:
|
||||
free_percpu(snet->stats);
|
||||
err2:
|
||||
- nf_conntrack_free(ct);
|
||||
+ nf_ct_tmpl_free(ct);
|
||||
err1:
|
||||
return err;
|
||||
}
|
||||
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
|
||||
index 43ddeee..f3377ce 100644
|
||||
--- a/net/netfilter/xt_CT.c
|
||||
+++ b/net/netfilter/xt_CT.c
|
||||
@@ -233,7 +233,7 @@ out:
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
- nf_conntrack_free(ct);
|
||||
+ nf_ct_tmpl_free(ct);
|
||||
err2:
|
||||
nf_ct_l3proto_module_put(par->family);
|
||||
err1:
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
From 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 Mon Sep 17 00:00:00 2001
|
||||
From: Elad Raz <eladr@mellanox.com>
|
||||
Date: Sat, 22 Aug 2015 08:44:11 +0300
|
||||
Subject: [PATCH] netfilter: ipset: Fixing unnamed union init
|
||||
|
||||
In continue to proposed Vinson Lee's post [1], this patch fixes compilation
|
||||
issues founded at gcc 4.4.7. The initialization of .cidr field of unnamed
|
||||
unions causes compilation error in gcc 4.4.x.
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
[1] https://lkml.org/lkml/2015/7/5/74
|
||||
|
||||
Signed-off-by: Elad Raz <eladr@mellanox.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
net/netfilter/ipset/ip_set_hash_netnet.c | 20 ++++++++++++++++++--
|
||||
net/netfilter/ipset/ip_set_hash_netportnet.c | 20 ++++++++++++++++++--
|
||||
2 files changed, 36 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
|
||||
index 3c862c0..a93dfeb 100644
|
||||
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
|
||||
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
|
||||
@@ -131,6 +131,13 @@ hash_netnet4_data_next(struct hash_netnet4_elem *next,
|
||||
#define HOST_MASK 32
|
||||
#include "ip_set_hash_gen.h"
|
||||
|
||||
+static void
|
||||
+hash_netnet4_init(struct hash_netnet4_elem *e)
|
||||
+{
|
||||
+ e->cidr[0] = HOST_MASK;
|
||||
+ e->cidr[1] = HOST_MASK;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
hash_netnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par,
|
||||
@@ -160,7 +167,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
{
|
||||
const struct hash_netnet *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
- struct hash_netnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
|
||||
+ struct hash_netnet4_elem e = { };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip = 0, ip_to = 0, last;
|
||||
u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2;
|
||||
@@ -169,6 +176,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
|
||||
|
||||
+ hash_netnet4_init(&e);
|
||||
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
||||
!ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
@@ -357,6 +365,13 @@ hash_netnet6_data_next(struct hash_netnet4_elem *next,
|
||||
#define IP_SET_EMIT_CREATE
|
||||
#include "ip_set_hash_gen.h"
|
||||
|
||||
+static void
|
||||
+hash_netnet6_init(struct hash_netnet6_elem *e)
|
||||
+{
|
||||
+ e->cidr[0] = HOST_MASK;
|
||||
+ e->cidr[1] = HOST_MASK;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
hash_netnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par,
|
||||
@@ -385,13 +400,14 @@ hash_netnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
- struct hash_netnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
|
||||
+ struct hash_netnet6_elem e = { };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
int ret;
|
||||
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
|
||||
|
||||
+ hash_netnet6_init(&e);
|
||||
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
||||
!ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
|
||||
index 0c68734..9a14c23 100644
|
||||
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
|
||||
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
|
||||
@@ -142,6 +142,13 @@ hash_netportnet4_data_next(struct hash_netportnet4_elem *next,
|
||||
#define HOST_MASK 32
|
||||
#include "ip_set_hash_gen.h"
|
||||
|
||||
+static void
|
||||
+hash_netportnet4_init(struct hash_netportnet4_elem *e)
|
||||
+{
|
||||
+ e->cidr[0] = HOST_MASK;
|
||||
+ e->cidr[1] = HOST_MASK;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par,
|
||||
@@ -175,7 +182,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
{
|
||||
const struct hash_netportnet *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
- struct hash_netportnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
|
||||
+ struct hash_netportnet4_elem e = { };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to;
|
||||
u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
|
||||
@@ -185,6 +192,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
|
||||
|
||||
+ hash_netportnet4_init(&e);
|
||||
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
||||
!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
|
||||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
|
||||
@@ -412,6 +420,13 @@ hash_netportnet6_data_next(struct hash_netportnet4_elem *next,
|
||||
#define IP_SET_EMIT_CREATE
|
||||
#include "ip_set_hash_gen.h"
|
||||
|
||||
+static void
|
||||
+hash_netportnet6_init(struct hash_netportnet6_elem *e)
|
||||
+{
|
||||
+ e->cidr[0] = HOST_MASK;
|
||||
+ e->cidr[1] = HOST_MASK;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
hash_netportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par,
|
||||
@@ -445,7 +460,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
{
|
||||
const struct hash_netportnet *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
- struct hash_netportnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
|
||||
+ struct hash_netportnet6_elem e = { };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 port, port_to;
|
||||
bool with_ports = false;
|
||||
@@ -454,6 +469,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
|
||||
|
||||
+ hash_netportnet6_init(&e);
|
||||
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
||||
!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
|
||||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
From 6fe7ccfd77415a6ba250c10c580eb3f9acf79753 Mon Sep 17 00:00:00 2001
|
||||
From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
Date: Tue, 25 Aug 2015 11:17:51 +0200
|
||||
Subject: [PATCH] netfilter: ipset: Out of bound access in hash:net* types
|
||||
fixed
|
||||
|
||||
Dave Jones reported that KASan detected out of bounds access in hash:net*
|
||||
types:
|
||||
|
||||
[ 23.139532] ==================================================================
|
||||
[ 23.146130] BUG: KASan: out of bounds access in hash_net4_add_cidr+0x1db/0x220 at addr ffff8800d4844b58
|
||||
[ 23.152937] Write of size 4 by task ipset/457
|
||||
[ 23.159742] =============================================================================
|
||||
[ 23.166672] BUG kmalloc-512 (Not tainted): kasan: bad access detected
|
||||
[ 23.173641] -----------------------------------------------------------------------------
|
||||
[ 23.194668] INFO: Allocated in hash_net_create+0x16a/0x470 age=7 cpu=1 pid=456
|
||||
[ 23.201836] __slab_alloc.constprop.66+0x554/0x620
|
||||
[ 23.208994] __kmalloc+0x2f2/0x360
|
||||
[ 23.216105] hash_net_create+0x16a/0x470
|
||||
[ 23.223238] ip_set_create+0x3e6/0x740
|
||||
[ 23.230343] nfnetlink_rcv_msg+0x599/0x640
|
||||
[ 23.237454] netlink_rcv_skb+0x14f/0x190
|
||||
[ 23.244533] nfnetlink_rcv+0x3f6/0x790
|
||||
[ 23.251579] netlink_unicast+0x272/0x390
|
||||
[ 23.258573] netlink_sendmsg+0x5a1/0xa50
|
||||
[ 23.265485] SYSC_sendto+0x1da/0x2c0
|
||||
[ 23.272364] SyS_sendto+0xe/0x10
|
||||
[ 23.279168] entry_SYSCALL_64_fastpath+0x12/0x6f
|
||||
|
||||
The bug is fixed in the patch and the testsuite is extended in ipset
|
||||
to check cidr handling more thoroughly.
|
||||
|
||||
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
---
|
||||
net/netfilter/ipset/ip_set_hash_gen.h | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
|
||||
index afe905c..691b54f 100644
|
||||
--- a/net/netfilter/ipset/ip_set_hash_gen.h
|
||||
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
|
||||
@@ -152,9 +152,13 @@ htable_bits(u32 hashsize)
|
||||
#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
|
||||
|
||||
#ifdef IP_SET_HASH_WITH_NET0
|
||||
+/* cidr from 0 to SET_HOST_MASK() value and c = cidr + 1 */
|
||||
#define NLEN(family) (SET_HOST_MASK(family) + 1)
|
||||
+#define CIDR_POS(c) ((c) - 1)
|
||||
#else
|
||||
+/* cidr from 1 to SET_HOST_MASK() value and c = cidr + 1 */
|
||||
#define NLEN(family) SET_HOST_MASK(family)
|
||||
+#define CIDR_POS(c) ((c) - 2)
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -305,7 +309,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
|
||||
} else if (h->nets[i].cidr[n] < cidr) {
|
||||
j = i;
|
||||
} else if (h->nets[i].cidr[n] == cidr) {
|
||||
- h->nets[cidr - 1].nets[n]++;
|
||||
+ h->nets[CIDR_POS(cidr)].nets[n]++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -314,7 +318,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
|
||||
h->nets[i].cidr[n] = h->nets[i - 1].cidr[n];
|
||||
}
|
||||
h->nets[i].cidr[n] = cidr;
|
||||
- h->nets[cidr - 1].nets[n] = 1;
|
||||
+ h->nets[CIDR_POS(cidr)].nets[n] = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -325,8 +329,8 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
|
||||
for (i = 0; i < nets_length; i++) {
|
||||
if (h->nets[i].cidr[n] != cidr)
|
||||
continue;
|
||||
- h->nets[cidr - 1].nets[n]--;
|
||||
- if (h->nets[cidr - 1].nets[n] > 0)
|
||||
+ h->nets[CIDR_POS(cidr)].nets[n]--;
|
||||
+ if (h->nets[CIDR_POS(cidr)].nets[n] > 0)
|
||||
return;
|
||||
for (j = i; j < net_end && h->nets[j].cidr[n]; j++)
|
||||
h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From bf798657eb5ba57552096843c315f096fdf9b715 Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Wed, 12 Aug 2015 17:41:00 +0200
|
||||
Subject: [PATCH] netfilter: nf_tables: Use 32 bit addressing register from
|
||||
nft_type_to_reg()
|
||||
|
||||
nft_type_to_reg() needs to return the register in the new 32 bit addressing,
|
||||
otherwise we hit EINVAL when using mappings.
|
||||
|
||||
Fixes: 49499c3 ("netfilter: nf_tables: switch registers to 32 bit addressing")
|
||||
Reported-by: Andreas Schultz <aschultz@tpip.net>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
include/net/netfilter/nf_tables.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
|
||||
index 2a24668..aa8bee7 100644
|
||||
--- a/include/net/netfilter/nf_tables.h
|
||||
+++ b/include/net/netfilter/nf_tables.h
|
||||
@@ -125,7 +125,7 @@ static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg)
|
||||
|
||||
static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
|
||||
{
|
||||
- return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
|
||||
+ return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE;
|
||||
}
|
||||
|
||||
unsigned int nft_parse_register(const struct nlattr *attr);
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
From a9de9777d613500b089a7416f936bf3ae5f070d2 Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Fri, 28 Aug 2015 21:01:43 +0200
|
||||
Subject: [PATCH] netfilter: nfnetlink: work around wrong endianess in res_id
|
||||
field
|
||||
|
||||
The convention in nfnetlink is to use network byte order in every header field
|
||||
as well as in the attribute payload. The initial version of the batching
|
||||
infrastructure assumes that res_id comes in host byte order though.
|
||||
|
||||
The only client of the batching infrastructure is nf_tables, so let's add a
|
||||
workaround to address this inconsistency. We currently have 11 nfnetlink
|
||||
subsystems according to NFNL_SUBSYS_COUNT, so we can assume that the subsystem
|
||||
2560, ie. htons(10), will not be allocated anytime soon, so it can be an alias
|
||||
of nf_tables from the nfnetlink batching path when interpreting the res_id
|
||||
field.
|
||||
|
||||
Based on original patch from Florian Westphal.
|
||||
|
||||
Reported-by: Florian Westphal <fw@strlen.de>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
net/netfilter/nfnetlink.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
|
||||
index 0c0e8ec..70277b1 100644
|
||||
--- a/net/netfilter/nfnetlink.c
|
||||
+++ b/net/netfilter/nfnetlink.c
|
||||
@@ -444,6 +444,7 @@ done:
|
||||
static void nfnetlink_rcv(struct sk_buff *skb)
|
||||
{
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(skb);
|
||||
+ u_int16_t res_id;
|
||||
int msglen;
|
||||
|
||||
if (nlh->nlmsg_len < NLMSG_HDRLEN ||
|
||||
@@ -468,7 +469,12 @@ static void nfnetlink_rcv(struct sk_buff *skb)
|
||||
|
||||
nfgenmsg = nlmsg_data(nlh);
|
||||
skb_pull(skb, msglen);
|
||||
- nfnetlink_rcv_batch(skb, nlh, nfgenmsg->res_id);
|
||||
+ /* Work around old nft using host byte order */
|
||||
+ if (nfgenmsg->res_id == NFNL_SUBSYS_NFTABLES)
|
||||
+ res_id = NFNL_SUBSYS_NFTABLES;
|
||||
+ else
|
||||
+ res_id = ntohs(nfgenmsg->res_id);
|
||||
+ nfnetlink_rcv_batch(skb, nlh, res_id);
|
||||
} else {
|
||||
netlink_rcv_skb(skb, &nfnetlink_rcv_msg);
|
||||
}
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Subject: [PATCH] rtlwifi: rtl8821ae: Fix system lockups on boot
|
||||
Date: Fri, 2 Oct 2015 11:44:30 -0500
|
||||
|
||||
In commit 1277fa2ab2f9, the code that cleared all interrupt enable
|
||||
bits before setting them was removed for all PCI drivers. This fixed an
|
||||
issue that caused TX to be blocked for 3-5 seconds. On some RTL8821AE units,
|
||||
this change causes soft lockups to occur on boot. For that reason, the portion
|
||||
of the earlier commit that applied to rtl8821ae is reverted. Kernels 4.1 and
|
||||
newer are affected.
|
||||
|
||||
See http://marc.info/?l=linux-wireless&m=144373370103285&w=2 and
|
||||
https://bugzilla.opensuse.org/show_bug.cgi?id=944978 for two cases where
|
||||
this regression affected user systems. Note that this bug does not appear on
|
||||
any of the developer's setups. For those users whose systems are affected
|
||||
by the TX blockage, but do not lock up on boot, a module parameter is added
|
||||
to disable the interrupt clear
|
||||
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Cc: Stable <stable@vger.kernel.org> [V4.1+]
|
||||
---
|
||||
|
||||
Kalle,
|
||||
|
||||
If possible, please send this patch upstream for inclusion in kernel 4.3.
|
||||
As noted, the bug affects kernels 4.1 and newer.
|
||||
|
||||
This patch applies to wireless-drivers-next, and assumes that the patch that
|
||||
moved all the Realtek drivers into drivers/net/wireless/realtek has NOT been
|
||||
applied.
|
||||
|
||||
Thanks,
|
||||
|
||||
Larry
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/pci.h | 2 ++
|
||||
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c | 17 +++++++++++++++++
|
||||
drivers/net/wireless/rtlwifi/rtl8821ae/sw.c | 5 +++++
|
||||
drivers/net/wireless/rtlwifi/wifi.h | 3 +++
|
||||
4 files changed, 27 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
|
||||
index d4567d1..5da6703 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/pci.h
|
||||
+++ b/drivers/net/wireless/rtlwifi/pci.h
|
||||
@@ -247,6 +247,8 @@ struct rtl_pci {
|
||||
/* MSI support */
|
||||
bool msi_support;
|
||||
bool using_msi;
|
||||
+ /* interrupt clear before set */
|
||||
+ bool int_clear;
|
||||
};
|
||||
|
||||
struct mp_adapter {
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
|
||||
index b7f18e21..6e9418e 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
|
||||
@@ -2253,11 +2253,28 @@ void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
|
||||
}
|
||||
}
|
||||
|
||||
+static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw)
|
||||
+{
|
||||
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
+ u32 tmp = rtl_read_dword(rtlpriv, REG_HISR);
|
||||
+
|
||||
+ rtl_write_dword(rtlpriv, REG_HISR, tmp);
|
||||
+
|
||||
+ tmp = rtl_read_dword(rtlpriv, REG_HISRE);
|
||||
+ rtl_write_dword(rtlpriv, REG_HISRE, tmp);
|
||||
+
|
||||
+ tmp = rtl_read_dword(rtlpriv, REG_HSISR);
|
||||
+ rtl_write_dword(rtlpriv, REG_HSISR, tmp);
|
||||
+}
|
||||
+
|
||||
void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
|
||||
+ if (!rtlpci->int_clear)
|
||||
+ rtl8821ae_clear_interrupt(hw);/*clear it here first*/
|
||||
+
|
||||
rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
|
||||
rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
|
||||
rtlpci->irq_enabled = true;
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
|
||||
index a4988121..8ee141a 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
|
||||
@@ -96,6 +96,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
||||
|
||||
rtl8821ae_bt_reg_init(hw);
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
+ rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
|
||||
|
||||
rtlpriv->dm.dm_initialgain_enable = 1;
|
||||
@@ -167,6 +168,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
||||
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
|
||||
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
+ rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
|
||||
if (rtlpriv->cfg->mod_params->disable_watchdog)
|
||||
pr_info("watchdog disabled\n");
|
||||
rtlpriv->psc.reg_fwctrl_lps = 3;
|
||||
@@ -308,6 +310,7 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
|
||||
.swctrl_lps = false,
|
||||
.fwctrl_lps = true,
|
||||
.msi_support = true,
|
||||
+ .int_clear = true,
|
||||
.debug = DBG_EMERG,
|
||||
.disable_watchdog = 0,
|
||||
};
|
||||
@@ -437,6 +440,7 @@ module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
|
||||
module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
|
||||
module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
|
||||
bool, 0444);
|
||||
+module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444);
|
||||
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
|
||||
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
|
||||
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
|
||||
@@ -444,6 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
|
||||
MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
|
||||
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
|
||||
MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
|
||||
+MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
|
||||
index b90ca61..4544752 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/wifi.h
|
||||
+++ b/drivers/net/wireless/rtlwifi/wifi.h
|
||||
@@ -2249,6 +2249,9 @@ struct rtl_mod_params {
|
||||
|
||||
/* default 0: 1 means disable */
|
||||
bool disable_watchdog;
|
||||
+
|
||||
+ /* default 0: 1 means do not disable interrupts */
|
||||
+ bool int_clear;
|
||||
};
|
||||
|
||||
struct rtl_hal_usbint_cfg {
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@@ -14,36 +14,6 @@
|
||||
###
|
||||
### Stable Queue
|
||||
###
|
||||
stable-phylib-fix-device-deletion-order-in-mdiobus_unregister.patch
|
||||
stable-sock-diag-fix-panic-in-sock_diag_put_filterinfo.patch
|
||||
stable-ipv6-fix-exthdrs-offload-registration-in-out_rt-path.patch
|
||||
stable-net-fec-clear-receive-interrupts-before-processing-a-packet.patch
|
||||
stable-net-eth-altera-fix-napi-poll_list-corruption.patch
|
||||
stable-net-ipv6-correct-pim6-mrt_lock-handling.patch
|
||||
stable-net-dsa-bcm_sf2-fix-ageing-conditions-and-operation.patch
|
||||
stable-ipv6-fix-multipath-route-replace-error-recovery.patch
|
||||
stable-net-dsa-bcm_sf2-fix-64-bits-register-writes.patch
|
||||
stable-netlink-mmap-transform-mmap-skb-into-full-skb-on-taps.patch
|
||||
stable-sctp-fix-race-on-protocol-netns-initialization.patch
|
||||
stable-bridge-fix-igmpv3-mldv2-report-parsing.patch
|
||||
stable-net-mvneta-fix-dma-buffer-unmapping-in-mvneta_rx.patch
|
||||
stable-rtnetlink-catch-eopnotsupp-errors-from-ndo_bridge_getlink.patch
|
||||
stable-net-mlx4_en-really-allow-to-change-rss-key.patch
|
||||
stable-macvtap-fix-tunsetsndbuf-values-64k.patch
|
||||
stable-netlink-fix-autobind-race-condition-that-leads-to-zero-port-id.patch
|
||||
stable-netlink-replace-rhash_portid-with-bound.patch
|
||||
stable-net-dsa-actually-force-the-speed-on-the-cpu-port.patch
|
||||
stable-openvswitch-zero-flows-on-allocation.patch
|
||||
stable-tcp-add-proper-ts-val-into-rst-packets.patch
|
||||
stable-fix-af_packet-abi-breakage-in-4.2.patch
|
||||
stable-net-revert-net_sched-move-tp-root-allocation-into-fw_init.patch
|
||||
stable-fib_rules-fix-fib-rule-dumps-across-multiple-skbs.patch
|
||||
stable-ppp-fix-lockdep-splat-in-ppp_dev_uninit.patch
|
||||
stable-net-dsa-bcm_sf2-do-not-override-speed-settings.patch
|
||||
stable-net-phy-fixed_phy-handle-link-down-case.patch
|
||||
stable-of_mdio-add-new-dt-property-managed-to-specify-the-phy-management-type.patch
|
||||
stable-mvneta-use-inband-status-only-when-explicitly-enabled.patch
|
||||
stable-net-mlx4_core-capping-number-of-requested-msixs-to-max_msix.patch
|
||||
|
||||
###
|
||||
### Arch x86
|
||||
@@ -68,6 +38,9 @@ x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch
|
||||
# slows down boot
|
||||
Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch
|
||||
|
||||
# efi bootfix
|
||||
x86-efi-Fix-boot-crash-by-mapping-EFI-memmap-entries.patch
|
||||
|
||||
###
|
||||
### Core
|
||||
###
|
||||
@@ -157,6 +130,10 @@ scsi-Fix-NULL-pointer-dereference-in-RTPM-of-block-layer.patch
|
||||
fs-aufs4.patch
|
||||
fs-aufs4-modular.patch
|
||||
|
||||
# Bind mount escape fixes (CVE-2015-2925)
|
||||
fs-dcache-Handle-escaped-paths-in-prepend_path.patch
|
||||
fs-vfs-Test-for-and-handle-paths-that-are-unreachable-from-their-mnt_root.patch
|
||||
|
||||
###
|
||||
### FireWire
|
||||
###
|
||||
@@ -240,6 +217,17 @@ net-netfilter-psd.patch
|
||||
net-netfilter-psd-mdv.patch
|
||||
net-netfilter-psd-2.6.35-buildfix.patch
|
||||
|
||||
# netfilter fixes
|
||||
net-netfilter-conntrack-use-nf_ct_tmpl_free-in-CT-synpro.patch
|
||||
net-netfilter-nfnetlink-work-around-wrong-endianess-in-r.patch
|
||||
net-netfilter-bridge-fix-IPv6-packets-not-being-bridged-.patch
|
||||
net-netfilter-nf_tables-Use-32-bit-addressing-register-f.patch
|
||||
net-netfilter-ipset-Out-of-bound-access-in-hash-net-type.patch
|
||||
net-netfilter-ipset-Fixing-unnamed-union-init.patch
|
||||
|
||||
# wireless lockup
|
||||
net-wireless-rtlwifi-rtl8821ae-Fix-system-lockups-on-boot.patch
|
||||
|
||||
###
|
||||
### Platform drivers
|
||||
###
|
||||
@@ -274,6 +262,10 @@ include-kbuild-export-pci_ids.patch
|
||||
### TTY
|
||||
###
|
||||
|
||||
###
|
||||
### Thunderbolt
|
||||
thunderbolt-Allow-loading-of-module-on-recent-Apple-.patch
|
||||
|
||||
###
|
||||
### USB
|
||||
###
|
||||
@@ -283,6 +275,12 @@ hid-usbhid-IBM-BladeCenterHS20-quirk.patch
|
||||
usb-storage-unusual_devs-add-id.patch
|
||||
usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch
|
||||
|
||||
# boot hang fix
|
||||
usb-phy-phy-generic-Fix-reset-behaviour-on-legacy-bo.patch
|
||||
|
||||
# xhci 1.1 support
|
||||
usb-xhci-change-xhci-1.0-only-restrictions-to-support-xh.patch
|
||||
|
||||
###
|
||||
### V4L
|
||||
###
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
|
||||
Date: Fri, 11 Sep 2015 18:39:48 +0200
|
||||
Subject: bridge: fix igmpv3 / mldv2 report parsing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
|
||||
|
||||
[ Upstream commit c2d4fbd2163e607915cc05798ce7fb7f31117cc1 ]
|
||||
|
||||
With the newly introduced helper functions the skb pulling is hidden in
|
||||
the checksumming function - and undone before returning to the caller.
|
||||
|
||||
The IGMPv3 and MLDv2 report parsing functions in the bridge still
|
||||
assumed that the skb is pointing to the beginning of the IGMP/MLD
|
||||
message while it is now kept at the beginning of the IPv4/6 header,
|
||||
breaking the message parsing and creating packet loss.
|
||||
|
||||
Fixing this by taking the offset between IP and IGMP/MLD header into
|
||||
account, too.
|
||||
|
||||
Fixes: 9afd85c9e455 ("net: Export IGMP/MLD message validation code")
|
||||
Reported-by: Tobias Powalowski <tobias.powalowski@googlemail.com>
|
||||
Tested-by: Tobias Powalowski <tobias.powalowski@googlemail.com>
|
||||
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/bridge/br_multicast.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/bridge/br_multicast.c
|
||||
+++ b/net/bridge/br_multicast.c
|
||||
@@ -991,7 +991,7 @@ static int br_ip4_multicast_igmp3_report
|
||||
|
||||
ih = igmpv3_report_hdr(skb);
|
||||
num = ntohs(ih->ngrec);
|
||||
- len = sizeof(*ih);
|
||||
+ len = skb_transport_offset(skb) + sizeof(*ih);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
len += sizeof(*grec);
|
||||
@@ -1052,7 +1052,7 @@ static int br_ip6_multicast_mld2_report(
|
||||
|
||||
icmp6h = icmp6_hdr(skb);
|
||||
num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
|
||||
- len = sizeof(*icmp6h);
|
||||
+ len = skb_transport_offset(skb) + sizeof(*icmp6h);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
__be16 *nsrcs, _nsrcs;
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Wilson Kok <wkok@cumulusnetworks.com>
|
||||
Date: Tue, 22 Sep 2015 21:40:22 -0700
|
||||
Subject: fib_rules: fix fib rule dumps across multiple skbs
|
||||
|
||||
From: Wilson Kok <wkok@cumulusnetworks.com>
|
||||
|
||||
[ Upstream commit 41fc014332d91ee90c32840bf161f9685b7fbf2b ]
|
||||
|
||||
dump_rules returns skb length and not error.
|
||||
But when family == AF_UNSPEC, the caller of dump_rules
|
||||
assumes that it returns an error. Hence, when family == AF_UNSPEC,
|
||||
we continue trying to dump on -EMSGSIZE errors resulting in
|
||||
incorrect dump idx carried between skbs belonging to the same dump.
|
||||
This results in fib rule dump always only dumping rules that fit
|
||||
into the first skb.
|
||||
|
||||
This patch fixes dump_rules to return error so that we exit correctly
|
||||
and idx is correctly maintained between skbs that are part of the
|
||||
same dump.
|
||||
|
||||
Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
|
||||
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/fib_rules.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/net/core/fib_rules.c
|
||||
+++ b/net/core/fib_rules.c
|
||||
@@ -615,15 +615,17 @@ static int dump_rules(struct sk_buff *sk
|
||||
{
|
||||
int idx = 0;
|
||||
struct fib_rule *rule;
|
||||
+ int err = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(rule, &ops->rules_list, list) {
|
||||
if (idx < cb->args[1])
|
||||
goto skip;
|
||||
|
||||
- if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
|
||||
- cb->nlh->nlmsg_seq, RTM_NEWRULE,
|
||||
- NLM_F_MULTI, ops) < 0)
|
||||
+ err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
|
||||
+ cb->nlh->nlmsg_seq, RTM_NEWRULE,
|
||||
+ NLM_F_MULTI, ops);
|
||||
+ if (err)
|
||||
break;
|
||||
skip:
|
||||
idx++;
|
||||
@@ -632,7 +634,7 @@ skip:
|
||||
cb->args[1] = idx;
|
||||
rules_ops_put(ops);
|
||||
|
||||
- return skb->len;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
@@ -648,7 +650,9 @@ static int fib_nl_dumprule(struct sk_buf
|
||||
if (ops == NULL)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
- return dump_rules(skb, cb, ops);
|
||||
+ dump_rules(skb, cb, ops);
|
||||
+
|
||||
+ return skb->len;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -1,114 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Wed, 23 Sep 2015 19:45:08 +0100
|
||||
Subject: Fix AF_PACKET ABI breakage in 4.2
|
||||
|
||||
From: David Woodhouse <dwmw2@infradead.org>
|
||||
|
||||
[ Upstream commit d3869efe7a8a2298516d9af4f91487cf486ca945 ]
|
||||
|
||||
Commit 7d82410950aa ("virtio: add explicit big-endian support to memory
|
||||
accessors") accidentally changed the virtio_net header used by
|
||||
AF_PACKET with PACKET_VNET_HDR from host-endian to big-endian.
|
||||
|
||||
Since virtio_legacy_is_little_endian() is a very long identifier,
|
||||
define a vio_le macro and use that throughout the code instead of the
|
||||
hard-coded 'false' for little-endian.
|
||||
|
||||
This restores the ABI to match 4.1 and earlier kernels, and makes my
|
||||
test program work again.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/packet/af_packet.c | 32 +++++++++++++++++---------------
|
||||
1 file changed, 17 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -229,6 +229,8 @@ struct packet_skb_cb {
|
||||
} sa;
|
||||
};
|
||||
|
||||
+#define vio_le() virtio_legacy_is_little_endian()
|
||||
+
|
||||
#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
|
||||
|
||||
#define GET_PBDQC_FROM_RB(x) ((struct tpacket_kbdq_core *)(&(x)->prb_bdqc))
|
||||
@@ -2561,15 +2563,15 @@ static int packet_snd(struct socket *soc
|
||||
goto out_unlock;
|
||||
|
||||
if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
|
||||
- (__virtio16_to_cpu(false, vnet_hdr.csum_start) +
|
||||
- __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 >
|
||||
- __virtio16_to_cpu(false, vnet_hdr.hdr_len)))
|
||||
- vnet_hdr.hdr_len = __cpu_to_virtio16(false,
|
||||
- __virtio16_to_cpu(false, vnet_hdr.csum_start) +
|
||||
- __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2);
|
||||
+ (__virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) +
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2 >
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len)))
|
||||
+ vnet_hdr.hdr_len = __cpu_to_virtio16(vio_le(),
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) +
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2);
|
||||
|
||||
err = -EINVAL;
|
||||
- if (__virtio16_to_cpu(false, vnet_hdr.hdr_len) > len)
|
||||
+ if (__virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len) > len)
|
||||
goto out_unlock;
|
||||
|
||||
if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
|
||||
@@ -2612,7 +2614,7 @@ static int packet_snd(struct socket *soc
|
||||
hlen = LL_RESERVED_SPACE(dev);
|
||||
tlen = dev->needed_tailroom;
|
||||
skb = packet_alloc_skb(sk, hlen + tlen, hlen, len,
|
||||
- __virtio16_to_cpu(false, vnet_hdr.hdr_len),
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len),
|
||||
msg->msg_flags & MSG_DONTWAIT, &err);
|
||||
if (skb == NULL)
|
||||
goto out_unlock;
|
||||
@@ -2659,8 +2661,8 @@ static int packet_snd(struct socket *soc
|
||||
|
||||
if (po->has_vnet_hdr) {
|
||||
if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
|
||||
- u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start);
|
||||
- u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset);
|
||||
+ u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start);
|
||||
+ u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset);
|
||||
if (!skb_partial_csum_set(skb, s, o)) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
@@ -2668,7 +2670,7 @@ static int packet_snd(struct socket *soc
|
||||
}
|
||||
|
||||
skb_shinfo(skb)->gso_size =
|
||||
- __virtio16_to_cpu(false, vnet_hdr.gso_size);
|
||||
+ __virtio16_to_cpu(vio_le(), vnet_hdr.gso_size);
|
||||
skb_shinfo(skb)->gso_type = gso_type;
|
||||
|
||||
/* Header must be checked, and gso_segs computed. */
|
||||
@@ -3042,9 +3044,9 @@ static int packet_recvmsg(struct socket
|
||||
|
||||
/* This is a hint as to how much should be linear. */
|
||||
vnet_hdr.hdr_len =
|
||||
- __cpu_to_virtio16(false, skb_headlen(skb));
|
||||
+ __cpu_to_virtio16(vio_le(), skb_headlen(skb));
|
||||
vnet_hdr.gso_size =
|
||||
- __cpu_to_virtio16(false, sinfo->gso_size);
|
||||
+ __cpu_to_virtio16(vio_le(), sinfo->gso_size);
|
||||
if (sinfo->gso_type & SKB_GSO_TCPV4)
|
||||
vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
|
||||
else if (sinfo->gso_type & SKB_GSO_TCPV6)
|
||||
@@ -3062,9 +3064,9 @@ static int packet_recvmsg(struct socket
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
|
||||
- vnet_hdr.csum_start = __cpu_to_virtio16(false,
|
||||
+ vnet_hdr.csum_start = __cpu_to_virtio16(vio_le(),
|
||||
skb_checksum_start_offset(skb));
|
||||
- vnet_hdr.csum_offset = __cpu_to_virtio16(false,
|
||||
+ vnet_hdr.csum_offset = __cpu_to_virtio16(vio_le(),
|
||||
skb->csum_offset);
|
||||
} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
|
||||
vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Date: Thu, 3 Sep 2015 00:29:07 +0200
|
||||
Subject: ipv6: fix exthdrs offload registration in out_rt path
|
||||
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
|
||||
[ Upstream commit e41b0bedba0293b9e1e8d1e8ed553104b9693656 ]
|
||||
|
||||
We previously register IPPROTO_ROUTING offload under inet6_add_offload(),
|
||||
but in error path, we try to unregister it with inet_del_offload(). This
|
||||
doesn't seem correct, it should actually be inet6_del_offload(), also
|
||||
ipv6_exthdrs_offload_exit() from that commit seems rather incorrect (it
|
||||
also uses rthdr_offload twice), but it got removed entirely later on.
|
||||
|
||||
Fixes: 3336288a9fea ("ipv6: Switch to using new offload infrastructure.")
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/exthdrs_offload.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/ipv6/exthdrs_offload.c
|
||||
+++ b/net/ipv6/exthdrs_offload.c
|
||||
@@ -36,6 +36,6 @@ out:
|
||||
return ret;
|
||||
|
||||
out_rt:
|
||||
- inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
||||
+ inet6_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
||||
goto out;
|
||||
}
|
||||
-352
@@ -1,352 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
Date: Tue, 8 Sep 2015 10:53:04 -0700
|
||||
Subject: ipv6: fix multipath route replace error recovery
|
||||
|
||||
From: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
|
||||
[ Upstream commit 6b9ea5a64ed5eeb3f68f2e6fcce0ed1179801d1e ]
|
||||
|
||||
Problem:
|
||||
The ecmp route replace support for ipv6 in the kernel, deletes the
|
||||
existing ecmp route too early, ie when it installs the first nexthop.
|
||||
If there is an error in installing the subsequent nexthops, its too late
|
||||
to recover the already deleted existing route leaving the fib
|
||||
in an inconsistent state.
|
||||
|
||||
This patch reduces the possibility of this by doing the following:
|
||||
a) Changes the existing multipath route add code to a two stage process:
|
||||
build rt6_infos + insert them
|
||||
ip6_route_add rt6_info creation code is moved into
|
||||
ip6_route_info_create.
|
||||
b) This ensures that most errors are caught during building rt6_infos
|
||||
and we fail early
|
||||
c) Separates multipath add and del code. Because add needs the special
|
||||
two stage mode in a) and delete essentially does not care.
|
||||
d) In any event if the code fails during inserting a route again, a
|
||||
warning is printed (This should be unlikely)
|
||||
|
||||
Before the patch:
|
||||
$ip -6 route show
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:b dev swp49s0 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:d dev swp49s1 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:f dev swp49s2 metric 1024
|
||||
|
||||
/* Try replacing the route with a duplicate nexthop */
|
||||
$ip -6 route change 3000:1000:1000:1000::2/128 nexthop via
|
||||
fe80::202:ff:fe00:b dev swp49s0 nexthop via fe80::202:ff:fe00:d dev
|
||||
swp49s1 nexthop via fe80::202:ff:fe00:d dev swp49s1
|
||||
RTNETLINK answers: File exists
|
||||
|
||||
$ip -6 route show
|
||||
/* previously added ecmp route 3000:1000:1000:1000::2 dissappears from
|
||||
* kernel */
|
||||
|
||||
After the patch:
|
||||
$ip -6 route show
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:b dev swp49s0 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:d dev swp49s1 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:f dev swp49s2 metric 1024
|
||||
|
||||
/* Try replacing the route with a duplicate nexthop */
|
||||
$ip -6 route change 3000:1000:1000:1000::2/128 nexthop via
|
||||
fe80::202:ff:fe00:b dev swp49s0 nexthop via fe80::202:ff:fe00:d dev
|
||||
swp49s1 nexthop via fe80::202:ff:fe00:d dev swp49s1
|
||||
RTNETLINK answers: File exists
|
||||
|
||||
$ip -6 route show
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:b dev swp49s0 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:d dev swp49s1 metric 1024
|
||||
3000:1000:1000:1000::2 via fe80::202:ff:fe00:f dev swp49s2 metric 1024
|
||||
|
||||
Fixes: 27596472473a ("ipv6: fix ECMP route replacement")
|
||||
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
|
||||
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/route.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 175 insertions(+), 26 deletions(-)
|
||||
|
||||
--- a/net/ipv6/route.c
|
||||
+++ b/net/ipv6/route.c
|
||||
@@ -1727,7 +1727,7 @@ static int ip6_convert_metrics(struct mx
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-int ip6_route_add(struct fib6_config *cfg)
|
||||
+int ip6_route_info_create(struct fib6_config *cfg, struct rt6_info **rt_ret)
|
||||
{
|
||||
int err;
|
||||
struct net *net = cfg->fc_nlinfo.nl_net;
|
||||
@@ -1735,7 +1735,6 @@ int ip6_route_add(struct fib6_config *cf
|
||||
struct net_device *dev = NULL;
|
||||
struct inet6_dev *idev = NULL;
|
||||
struct fib6_table *table;
|
||||
- struct mx6_config mxc = { .mx = NULL, };
|
||||
int addr_type;
|
||||
|
||||
if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
|
||||
@@ -1941,6 +1940,32 @@ install_route:
|
||||
|
||||
cfg->fc_nlinfo.nl_net = dev_net(dev);
|
||||
|
||||
+ *rt_ret = rt;
|
||||
+
|
||||
+ return 0;
|
||||
+out:
|
||||
+ if (dev)
|
||||
+ dev_put(dev);
|
||||
+ if (idev)
|
||||
+ in6_dev_put(idev);
|
||||
+ if (rt)
|
||||
+ dst_free(&rt->dst);
|
||||
+
|
||||
+ *rt_ret = NULL;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+int ip6_route_add(struct fib6_config *cfg)
|
||||
+{
|
||||
+ struct mx6_config mxc = { .mx = NULL, };
|
||||
+ struct rt6_info *rt = NULL;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ip6_route_info_create(cfg, &rt);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
err = ip6_convert_metrics(&mxc, cfg);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -1948,14 +1973,12 @@ install_route:
|
||||
err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, &mxc);
|
||||
|
||||
kfree(mxc.mx);
|
||||
+
|
||||
return err;
|
||||
out:
|
||||
- if (dev)
|
||||
- dev_put(dev);
|
||||
- if (idev)
|
||||
- in6_dev_put(idev);
|
||||
if (rt)
|
||||
dst_free(&rt->dst);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2727,19 +2750,78 @@ errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
-static int ip6_route_multipath(struct fib6_config *cfg, int add)
|
||||
+struct rt6_nh {
|
||||
+ struct rt6_info *rt6_info;
|
||||
+ struct fib6_config r_cfg;
|
||||
+ struct mx6_config mxc;
|
||||
+ struct list_head next;
|
||||
+};
|
||||
+
|
||||
+static void ip6_print_replace_route_err(struct list_head *rt6_nh_list)
|
||||
+{
|
||||
+ struct rt6_nh *nh;
|
||||
+
|
||||
+ list_for_each_entry(nh, rt6_nh_list, next) {
|
||||
+ pr_warn("IPV6: multipath route replace failed (check consistency of installed routes): %pI6 nexthop %pI6 ifi %d\n",
|
||||
+ &nh->r_cfg.fc_dst, &nh->r_cfg.fc_gateway,
|
||||
+ nh->r_cfg.fc_ifindex);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int ip6_route_info_append(struct list_head *rt6_nh_list,
|
||||
+ struct rt6_info *rt, struct fib6_config *r_cfg)
|
||||
+{
|
||||
+ struct rt6_nh *nh;
|
||||
+ struct rt6_info *rtnh;
|
||||
+ int err = -EEXIST;
|
||||
+
|
||||
+ list_for_each_entry(nh, rt6_nh_list, next) {
|
||||
+ /* check if rt6_info already exists */
|
||||
+ rtnh = nh->rt6_info;
|
||||
+
|
||||
+ if (rtnh->dst.dev == rt->dst.dev &&
|
||||
+ rtnh->rt6i_idev == rt->rt6i_idev &&
|
||||
+ ipv6_addr_equal(&rtnh->rt6i_gateway,
|
||||
+ &rt->rt6i_gateway))
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ nh = kzalloc(sizeof(*nh), GFP_KERNEL);
|
||||
+ if (!nh)
|
||||
+ return -ENOMEM;
|
||||
+ nh->rt6_info = rt;
|
||||
+ err = ip6_convert_metrics(&nh->mxc, r_cfg);
|
||||
+ if (err) {
|
||||
+ kfree(nh);
|
||||
+ return err;
|
||||
+ }
|
||||
+ memcpy(&nh->r_cfg, r_cfg, sizeof(*r_cfg));
|
||||
+ list_add_tail(&nh->next, rt6_nh_list);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ip6_route_multipath_add(struct fib6_config *cfg)
|
||||
{
|
||||
struct fib6_config r_cfg;
|
||||
struct rtnexthop *rtnh;
|
||||
+ struct rt6_info *rt;
|
||||
+ struct rt6_nh *err_nh;
|
||||
+ struct rt6_nh *nh, *nh_safe;
|
||||
int remaining;
|
||||
int attrlen;
|
||||
- int err = 0, last_err = 0;
|
||||
+ int err = 1;
|
||||
+ int nhn = 0;
|
||||
+ int replace = (cfg->fc_nlinfo.nlh &&
|
||||
+ (cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_REPLACE));
|
||||
+ LIST_HEAD(rt6_nh_list);
|
||||
|
||||
remaining = cfg->fc_mp_len;
|
||||
-beginning:
|
||||
rtnh = (struct rtnexthop *)cfg->fc_mp;
|
||||
|
||||
- /* Parse a Multipath Entry */
|
||||
+ /* Parse a Multipath Entry and build a list (rt6_nh_list) of
|
||||
+ * rt6_info structs per nexthop
|
||||
+ */
|
||||
while (rtnh_ok(rtnh, remaining)) {
|
||||
memcpy(&r_cfg, cfg, sizeof(*cfg));
|
||||
if (rtnh->rtnh_ifindex)
|
||||
@@ -2755,22 +2837,32 @@ beginning:
|
||||
r_cfg.fc_flags |= RTF_GATEWAY;
|
||||
}
|
||||
}
|
||||
- err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg);
|
||||
+
|
||||
+ err = ip6_route_info_create(&r_cfg, &rt);
|
||||
+ if (err)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ err = ip6_route_info_append(&rt6_nh_list, rt, &r_cfg);
|
||||
if (err) {
|
||||
- last_err = err;
|
||||
- /* If we are trying to remove a route, do not stop the
|
||||
- * loop when ip6_route_del() fails (because next hop is
|
||||
- * already gone), we should try to remove all next hops.
|
||||
- */
|
||||
- if (add) {
|
||||
- /* If add fails, we should try to delete all
|
||||
- * next hops that have been already added.
|
||||
- */
|
||||
- add = 0;
|
||||
- remaining = cfg->fc_mp_len - remaining;
|
||||
- goto beginning;
|
||||
- }
|
||||
+ dst_free(&rt->dst);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ rtnh = rtnh_next(rtnh, &remaining);
|
||||
+ }
|
||||
+
|
||||
+ err_nh = NULL;
|
||||
+ list_for_each_entry(nh, &rt6_nh_list, next) {
|
||||
+ err = __ip6_ins_rt(nh->rt6_info, &cfg->fc_nlinfo, &nh->mxc);
|
||||
+ /* nh->rt6_info is used or freed at this point, reset to NULL*/
|
||||
+ nh->rt6_info = NULL;
|
||||
+ if (err) {
|
||||
+ if (replace && nhn)
|
||||
+ ip6_print_replace_route_err(&rt6_nh_list);
|
||||
+ err_nh = nh;
|
||||
+ goto add_errout;
|
||||
}
|
||||
+
|
||||
/* Because each route is added like a single route we remove
|
||||
* these flags after the first nexthop: if there is a collision,
|
||||
* we have already failed to add the first nexthop:
|
||||
@@ -2780,6 +2872,63 @@ beginning:
|
||||
*/
|
||||
cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL |
|
||||
NLM_F_REPLACE);
|
||||
+ nhn++;
|
||||
+ }
|
||||
+
|
||||
+ goto cleanup;
|
||||
+
|
||||
+add_errout:
|
||||
+ /* Delete routes that were already added */
|
||||
+ list_for_each_entry(nh, &rt6_nh_list, next) {
|
||||
+ if (err_nh == nh)
|
||||
+ break;
|
||||
+ ip6_route_del(&nh->r_cfg);
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ list_for_each_entry_safe(nh, nh_safe, &rt6_nh_list, next) {
|
||||
+ if (nh->rt6_info)
|
||||
+ dst_free(&nh->rt6_info->dst);
|
||||
+ if (nh->mxc.mx)
|
||||
+ kfree(nh->mxc.mx);
|
||||
+ list_del(&nh->next);
|
||||
+ kfree(nh);
|
||||
+ }
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int ip6_route_multipath_del(struct fib6_config *cfg)
|
||||
+{
|
||||
+ struct fib6_config r_cfg;
|
||||
+ struct rtnexthop *rtnh;
|
||||
+ int remaining;
|
||||
+ int attrlen;
|
||||
+ int err = 1, last_err = 0;
|
||||
+
|
||||
+ remaining = cfg->fc_mp_len;
|
||||
+ rtnh = (struct rtnexthop *)cfg->fc_mp;
|
||||
+
|
||||
+ /* Parse a Multipath Entry */
|
||||
+ while (rtnh_ok(rtnh, remaining)) {
|
||||
+ memcpy(&r_cfg, cfg, sizeof(*cfg));
|
||||
+ if (rtnh->rtnh_ifindex)
|
||||
+ r_cfg.fc_ifindex = rtnh->rtnh_ifindex;
|
||||
+
|
||||
+ attrlen = rtnh_attrlen(rtnh);
|
||||
+ if (attrlen > 0) {
|
||||
+ struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
|
||||
+
|
||||
+ nla = nla_find(attrs, attrlen, RTA_GATEWAY);
|
||||
+ if (nla) {
|
||||
+ nla_memcpy(&r_cfg.fc_gateway, nla, 16);
|
||||
+ r_cfg.fc_flags |= RTF_GATEWAY;
|
||||
+ }
|
||||
+ }
|
||||
+ err = ip6_route_del(&r_cfg);
|
||||
+ if (err)
|
||||
+ last_err = err;
|
||||
+
|
||||
rtnh = rtnh_next(rtnh, &remaining);
|
||||
}
|
||||
|
||||
@@ -2796,7 +2945,7 @@ static int inet6_rtm_delroute(struct sk_
|
||||
return err;
|
||||
|
||||
if (cfg.fc_mp)
|
||||
- return ip6_route_multipath(&cfg, 0);
|
||||
+ return ip6_route_multipath_del(&cfg);
|
||||
else
|
||||
return ip6_route_del(&cfg);
|
||||
}
|
||||
@@ -2811,7 +2960,7 @@ static int inet6_rtm_newroute(struct sk_
|
||||
return err;
|
||||
|
||||
if (cfg.fc_mp)
|
||||
- return ip6_route_multipath(&cfg, 1);
|
||||
+ return ip6_route_multipath_add(&cfg);
|
||||
else
|
||||
return ip6_route_add(&cfg);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Date: Fri, 18 Sep 2015 13:41:09 +0300
|
||||
Subject: macvtap: fix TUNSETSNDBUF values > 64k
|
||||
|
||||
From: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
|
||||
[ Upstream commit 3ea79249e81e5ed051f2e6480cbde896d99046e8 ]
|
||||
|
||||
Upon TUNSETSNDBUF, macvtap reads the requested sndbuf size into
|
||||
a local variable u.
|
||||
commit 39ec7de7092b ("macvtap: fix uninitialized access on
|
||||
TUNSETIFF") changed its type to u16 (which is the right thing to
|
||||
do for all other macvtap ioctls), breaking all values > 64k.
|
||||
|
||||
The value of TUNSETSNDBUF is actually a signed 32 bit integer, so
|
||||
the right thing to do is to read it into an int.
|
||||
|
||||
Cc: David S. Miller <davem@davemloft.net>
|
||||
Fixes: 39ec7de7092b ("macvtap: fix uninitialized access on TUNSETIFF")
|
||||
Reported-by: Mark A. Peloquin
|
||||
Bisected-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
|
||||
Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Tested-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
|
||||
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/macvtap.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/macvtap.c
|
||||
+++ b/drivers/net/macvtap.c
|
||||
@@ -1111,10 +1111,10 @@ static long macvtap_ioctl(struct file *f
|
||||
return 0;
|
||||
|
||||
case TUNSETSNDBUF:
|
||||
- if (get_user(u, up))
|
||||
+ if (get_user(s, sp))
|
||||
return -EFAULT;
|
||||
|
||||
- q->sk.sk_sndbuf = u;
|
||||
+ q->sk.sk_sndbuf = s;
|
||||
return 0;
|
||||
|
||||
case TUNGETVNETHDRSZ:
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
Date: Mon, 20 Jul 2015 17:49:58 -0700
|
||||
Subject: mvneta: use inband status only when explicitly enabled
|
||||
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
|
||||
[ Upstream commit f8af8e6eb95093d5ce5ebcc52bd1929b0433e172 in net-next tree,
|
||||
will be pushed to Linus very soon. ]
|
||||
|
||||
The commit 898b2970e2c9 ("mvneta: implement SGMII-based in-band link state
|
||||
signaling") implemented the link parameters auto-negotiation unconditionally.
|
||||
Unfortunately it appears that some HW that implements SGMII protocol,
|
||||
doesn't generate the inband status, so it is not possible to auto-negotiate
|
||||
anything with such HW.
|
||||
|
||||
This patch enables the auto-negotiation only if explicitly requested with
|
||||
the 'managed' DT property.
|
||||
|
||||
This patch fixes the following regression:
|
||||
https://lkml.org/lkml/2015/7/8/865
|
||||
|
||||
Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
|
||||
|
||||
CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
CC: netdev@vger.kernel.org
|
||||
CC: linux-kernel@vger.kernel.org
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/marvell/mvneta.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/marvell/mvneta.c
|
||||
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
||||
@@ -3029,8 +3029,8 @@ static int mvneta_probe(struct platform_
|
||||
const char *dt_mac_addr;
|
||||
char hw_mac_addr[ETH_ALEN];
|
||||
const char *mac_from;
|
||||
+ const char *managed;
|
||||
int phy_mode;
|
||||
- int fixed_phy = 0;
|
||||
int err;
|
||||
|
||||
/* Our multiqueue support is not complete, so for now, only
|
||||
@@ -3064,7 +3064,6 @@ static int mvneta_probe(struct platform_
|
||||
dev_err(&pdev->dev, "cannot register fixed PHY\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
- fixed_phy = 1;
|
||||
|
||||
/* In the case of a fixed PHY, the DT node associated
|
||||
* to the PHY is the Ethernet MAC DT node.
|
||||
@@ -3088,8 +3087,10 @@ static int mvneta_probe(struct platform_
|
||||
pp = netdev_priv(dev);
|
||||
pp->phy_node = phy_node;
|
||||
pp->phy_interface = phy_mode;
|
||||
- pp->use_inband_status = (phy_mode == PHY_INTERFACE_MODE_SGMII) &&
|
||||
- fixed_phy;
|
||||
+
|
||||
+ err = of_property_read_string(dn, "managed", &managed);
|
||||
+ pp->use_inband_status = (err == 0 &&
|
||||
+ strcmp(managed, "in-band-status") == 0);
|
||||
|
||||
pp->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(pp->clk)) {
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Date: Mon, 21 Sep 2015 21:42:59 +0100
|
||||
Subject: net: dsa: actually force the speed on the CPU port
|
||||
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
|
||||
[ Upstream commit 53adc9e83028d9e35b6408231ebaf62a94a16e4d ]
|
||||
|
||||
Commit 54d792f257c6 ("net: dsa: Centralise global and port setup
|
||||
code into mv88e6xxx.") merged in the 4.2 merge window broke the link
|
||||
speed forcing for the CPU port of Marvell DSA switches. The original
|
||||
code was:
|
||||
|
||||
/* MAC Forcing register: don't force link, speed, duplex
|
||||
* or flow control state to any particular values on physical
|
||||
* ports, but force the CPU port and all DSA ports to 1000 Mb/s
|
||||
* full duplex.
|
||||
*/
|
||||
if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
|
||||
REG_WRITE(addr, 0x01, 0x003e);
|
||||
else
|
||||
REG_WRITE(addr, 0x01, 0x0003);
|
||||
|
||||
but the new code does a read-modify-write:
|
||||
|
||||
reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL);
|
||||
if (dsa_is_cpu_port(ds, port) ||
|
||||
ds->dsa_port_mask & (1 << port)) {
|
||||
reg |= PORT_PCS_CTRL_FORCE_LINK |
|
||||
PORT_PCS_CTRL_LINK_UP |
|
||||
PORT_PCS_CTRL_DUPLEX_FULL |
|
||||
PORT_PCS_CTRL_FORCE_DUPLEX;
|
||||
if (mv88e6xxx_6065_family(ds))
|
||||
reg |= PORT_PCS_CTRL_100;
|
||||
else
|
||||
reg |= PORT_PCS_CTRL_1000;
|
||||
|
||||
The link speed in the PCS control register is a two bit field. Forcing
|
||||
the link speed in this way doesn't ensure that the bit field is set to
|
||||
the correct value - on the hardware I have here, the speed bitfield
|
||||
remains set to 0x03, resulting in the speed not being forced to gigabit.
|
||||
|
||||
We must clear both bits before forcing the link speed.
|
||||
|
||||
Fixes: 54d792f257c6 ("net: dsa: Centralise global and port setup code into mv88e6xxx.")
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Acked-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/dsa/mv88e6xxx.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx.c
|
||||
@@ -1387,6 +1387,7 @@ static int mv88e6xxx_setup_port(struct d
|
||||
reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL);
|
||||
if (dsa_is_cpu_port(ds, port) ||
|
||||
ds->dsa_port_mask & (1 << port)) {
|
||||
+ reg &= ~PORT_PCS_CTRL_UNFORCED;
|
||||
reg |= PORT_PCS_CTRL_FORCE_LINK |
|
||||
PORT_PCS_CTRL_LINK_UP |
|
||||
PORT_PCS_CTRL_DUPLEX_FULL |
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Date: Mon, 20 Jul 2015 17:49:55 -0700
|
||||
Subject: net: dsa: bcm_sf2: Do not override speed settings
|
||||
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
[ Upstream d2eac98f7d1b950b762a7eca05a9ce0ea1d878d2 in net-next tree,
|
||||
will be pushed to Linus very soon. ]
|
||||
|
||||
The SF2 driver currently overrides speed settings for its port
|
||||
configured using a fixed PHY, this is both unnecessary and incorrect,
|
||||
because we keep feedback to the hardware parameters that we read from
|
||||
the PHY device, which in the case of a fixed PHY cannot possibly change
|
||||
speed.
|
||||
|
||||
This is a required change to allow the fixed PHY code to allow
|
||||
registering a PHY with a link configured as DOWN by default and avoid
|
||||
some sort of circular dependency where we require the link_update
|
||||
callback to run to program the hardware, and we then utilize the fixed
|
||||
PHY parameters to program the hardware with the same settings.
|
||||
|
||||
Fixes: 246d7f773c13 ("net: dsa: add Broadcom SF2 switch driver")
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/dsa/bcm_sf2.c | 18 +-----------------
|
||||
1 file changed, 1 insertion(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/bcm_sf2.c
|
||||
+++ b/drivers/net/dsa/bcm_sf2.c
|
||||
@@ -905,15 +905,11 @@ static void bcm_sf2_sw_fixed_link_update
|
||||
struct fixed_phy_status *status)
|
||||
{
|
||||
struct bcm_sf2_priv *priv = ds_to_priv(ds);
|
||||
- u32 duplex, pause, speed;
|
||||
+ u32 duplex, pause;
|
||||
u32 reg;
|
||||
|
||||
duplex = core_readl(priv, CORE_DUPSTS);
|
||||
pause = core_readl(priv, CORE_PAUSESTS);
|
||||
- speed = core_readl(priv, CORE_SPDSTS);
|
||||
-
|
||||
- speed >>= (port * SPDSTS_SHIFT);
|
||||
- speed &= SPDSTS_MASK;
|
||||
|
||||
status->link = 0;
|
||||
|
||||
@@ -948,18 +944,6 @@ static void bcm_sf2_sw_fixed_link_update
|
||||
reg &= ~LINK_STS;
|
||||
core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port));
|
||||
|
||||
- switch (speed) {
|
||||
- case SPDSTS_10:
|
||||
- status->speed = SPEED_10;
|
||||
- break;
|
||||
- case SPDSTS_100:
|
||||
- status->speed = SPEED_100;
|
||||
- break;
|
||||
- case SPDSTS_1000:
|
||||
- status->speed = SPEED_1000;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
if ((pause & (1 << port)) &&
|
||||
(pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) {
|
||||
status->asym_pause = 1;
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Date: Tue, 8 Sep 2015 20:06:41 -0700
|
||||
Subject: net: dsa: bcm_sf2: Fix 64-bits register writes
|
||||
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
[ Upstream commit 03679a14739a0d4c14b52ba65a69ff553bfba73b ]
|
||||
|
||||
The macro to write 64-bits quantities to the 32-bits register swapped
|
||||
the value and offsets arguments, we want to preserve the ordering of the
|
||||
arguments with respect to how writel() is implemented for instance:
|
||||
value first, offset/base second.
|
||||
|
||||
Fixes: 246d7f773c13 ("net: dsa: add Broadcom SF2 switch driver")
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/dsa/bcm_sf2.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/bcm_sf2.h
|
||||
+++ b/drivers/net/dsa/bcm_sf2.h
|
||||
@@ -112,8 +112,8 @@ static inline u64 name##_readq(struct bc
|
||||
spin_unlock(&priv->indir_lock); \
|
||||
return (u64)indir << 32 | dir; \
|
||||
} \
|
||||
-static inline void name##_writeq(struct bcm_sf2_priv *priv, u32 off, \
|
||||
- u64 val) \
|
||||
+static inline void name##_writeq(struct bcm_sf2_priv *priv, u64 val, \
|
||||
+ u32 off) \
|
||||
{ \
|
||||
spin_lock(&priv->indir_lock); \
|
||||
reg_writel(priv, upper_32_bits(val), REG_DIR_DATA_WRITE); \
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Date: Sat, 5 Sep 2015 13:07:27 -0700
|
||||
Subject: net: dsa: bcm_sf2: Fix ageing conditions and operation
|
||||
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
[ Upstream commit 39797a279d62972cd914ef580fdfacb13e508bf8 ]
|
||||
|
||||
The comparison check between cur_hw_state and hw_state is currently
|
||||
invalid because cur_hw_state is right shifted by G_MISTP_SHIFT, while
|
||||
hw_state is not, so we end-up comparing bits 2:0 with bits 7:5, which is
|
||||
going to cause an additional aging to occur. Fix this by not shifting
|
||||
cur_hw_state while reading it, but instead, mask the value with the
|
||||
appropriately shitfted bitmask.
|
||||
|
||||
The other problem with the fast-ageing process is that we did not set
|
||||
the EN_AGE_DYNAMIC bit to request the ageing to occur for dynamically
|
||||
learned MAC addresses. Finally, write back 0 to the FAST_AGE_CTRL
|
||||
register to avoid leaving spurious bits sets from one operation to the
|
||||
other.
|
||||
|
||||
Fixes: 12f460f23423 ("net: dsa: bcm_sf2: add HW bridging support")
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/dsa/bcm_sf2.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/bcm_sf2.c
|
||||
+++ b/drivers/net/dsa/bcm_sf2.c
|
||||
@@ -418,7 +418,7 @@ static int bcm_sf2_sw_fast_age_port(stru
|
||||
core_writel(priv, port, CORE_FAST_AGE_PORT);
|
||||
|
||||
reg = core_readl(priv, CORE_FAST_AGE_CTRL);
|
||||
- reg |= EN_AGE_PORT | FAST_AGE_STR_DONE;
|
||||
+ reg |= EN_AGE_PORT | EN_AGE_DYNAMIC | FAST_AGE_STR_DONE;
|
||||
core_writel(priv, reg, CORE_FAST_AGE_CTRL);
|
||||
|
||||
do {
|
||||
@@ -432,6 +432,8 @@ static int bcm_sf2_sw_fast_age_port(stru
|
||||
if (!timeout)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
+ core_writel(priv, 0, CORE_FAST_AGE_CTRL);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -507,7 +509,7 @@ static int bcm_sf2_sw_br_set_stp_state(s
|
||||
u32 reg;
|
||||
|
||||
reg = core_readl(priv, CORE_G_PCTL_PORT(port));
|
||||
- cur_hw_state = reg >> G_MISTP_STATE_SHIFT;
|
||||
+ cur_hw_state = reg & (G_MISTP_STATE_MASK << G_MISTP_STATE_SHIFT);
|
||||
|
||||
switch (state) {
|
||||
case BR_STATE_DISABLED:
|
||||
@@ -531,10 +533,12 @@ static int bcm_sf2_sw_br_set_stp_state(s
|
||||
}
|
||||
|
||||
/* Fast-age ARL entries if we are moving a port from Learning or
|
||||
- * Forwarding state to Disabled, Blocking or Listening state
|
||||
+ * Forwarding (cur_hw_state) state to Disabled, Blocking or Listening
|
||||
+ * state (hw_state)
|
||||
*/
|
||||
if (cur_hw_state != hw_state) {
|
||||
- if (cur_hw_state & 4 && !(hw_state & 4)) {
|
||||
+ if (cur_hw_state >= G_MISTP_LEARN_STATE &&
|
||||
+ hw_state <= G_MISTP_LISTEN_STATE) {
|
||||
ret = bcm_sf2_sw_fast_age_port(ds, port);
|
||||
if (ret) {
|
||||
pr_err("%s: fast-ageing failed\n", __func__);
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Atsushi Nemoto <nemoto@toshiba-tops.co.jp>
|
||||
Date: Wed, 2 Sep 2015 17:49:29 +0900
|
||||
Subject: net: eth: altera: fix napi poll_list corruption
|
||||
|
||||
From: Atsushi Nemoto <nemoto@toshiba-tops.co.jp>
|
||||
|
||||
[ Upstream commit 4548a697e4969d695047cebd6d9af5e2f6cc728e ]
|
||||
|
||||
tse_poll() calls __napi_complete() with irq enabled. This leads napi
|
||||
poll_list corruption and may stop all napi drivers working.
|
||||
Use napi_complete() instead of __napi_complete().
|
||||
|
||||
Signed-off-by: Atsushi Nemoto <nemoto@toshiba-tops.co.jp>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/altera/altera_tse_main.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/altera/altera_tse_main.c
|
||||
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
|
||||
@@ -511,8 +511,7 @@ static int tse_poll(struct napi_struct *
|
||||
|
||||
if (rxcomplete < budget) {
|
||||
|
||||
- napi_gro_flush(napi, false);
|
||||
- __napi_complete(napi);
|
||||
+ napi_complete(napi);
|
||||
|
||||
netdev_dbg(priv->dev,
|
||||
"NAPI Complete, did %d packets with budget %d\n",
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Date: Wed, 2 Sep 2015 17:24:14 +0800
|
||||
Subject: net: fec: clear receive interrupts before processing a packet
|
||||
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
|
||||
[ Upstream commit ed63f1dcd5788d36f942fbcce350742385e3e18c ]
|
||||
|
||||
The patch just to re-submit the patch "db3421c114cfa6326" because the
|
||||
patch "4d494cdc92b3b9a0" remove the change.
|
||||
|
||||
Clear any pending receive interrupt before we process a pending packet.
|
||||
This helps to avoid any spurious interrupts being raised after we have
|
||||
fully cleaned the receive ring, while still allowing an interrupt to be
|
||||
raised if we receive another packet.
|
||||
|
||||
The position of this is critical: we must do this prior to reading the
|
||||
next packet status to avoid potentially dropping an interrupt when a
|
||||
packet is still pending.
|
||||
|
||||
Acked-by: Fugang Duan <B38611@freescale.com>
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/freescale/fec_main.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/ethernet/freescale/fec_main.c
|
||||
+++ b/drivers/net/ethernet/freescale/fec_main.c
|
||||
@@ -1402,6 +1402,7 @@ fec_enet_rx_queue(struct net_device *nde
|
||||
if ((status & BD_ENET_RX_LAST) == 0)
|
||||
netdev_err(ndev, "rcv is not +last\n");
|
||||
|
||||
+ writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
|
||||
|
||||
/* Check for errors. */
|
||||
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Richard Laing <richard.laing@alliedtelesis.co.nz>
|
||||
Date: Thu, 3 Sep 2015 13:52:31 +1200
|
||||
Subject: net/ipv6: Correct PIM6 mrt_lock handling
|
||||
|
||||
From: Richard Laing <richard.laing@alliedtelesis.co.nz>
|
||||
|
||||
[ Upstream commit 25b4a44c19c83d98e8c0807a7ede07c1f28eab8b ]
|
||||
|
||||
In the IPv6 multicast routing code the mrt_lock was not being released
|
||||
correctly in the MFC iterator, as a result adding or deleting a MIF would
|
||||
cause a hang because the mrt_lock could not be acquired.
|
||||
|
||||
This fix is a copy of the code for the IPv4 case and ensures that the lock
|
||||
is released correctly.
|
||||
|
||||
Signed-off-by: Richard Laing <richard.laing@alliedtelesis.co.nz>
|
||||
Acked-by: Cong Wang <cwang@twopensource.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/ip6mr.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/ipv6/ip6mr.c
|
||||
+++ b/net/ipv6/ip6mr.c
|
||||
@@ -550,7 +550,7 @@ static void ipmr_mfc_seq_stop(struct seq
|
||||
|
||||
if (it->cache == &mrt->mfc6_unres_queue)
|
||||
spin_unlock_bh(&mfc_unres_lock);
|
||||
- else if (it->cache == mrt->mfc6_cache_array)
|
||||
+ else if (it->cache == &mrt->mfc6_cache_array[it->ct])
|
||||
read_unlock(&mrt_lock);
|
||||
}
|
||||
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Carol L Soto <clsoto@linux.vnet.ibm.com>
|
||||
Date: Thu, 27 Aug 2015 14:43:25 -0500
|
||||
Subject: net/mlx4_core: Capping number of requested MSIXs to MAX_MSIX
|
||||
|
||||
From: Carol L Soto <clsoto@linux.vnet.ibm.com>
|
||||
|
||||
[ Upstream commit 9293267a3e2a7a2555d8ddc8f9301525e5b03b1b ]
|
||||
|
||||
We currently manage IRQs in pool_bm which is a bit field
|
||||
of MAX_MSIX bits. Thus, allocating more than MAX_MSIX
|
||||
interrupts can't be managed in pool_bm.
|
||||
Fixing this by capping number of requested MSIXs to
|
||||
MAX_MSIX.
|
||||
|
||||
Signed-off-by: Matan Barak <matanb@mellanox.com>
|
||||
Signed-off-by: Carol L Soto <clsoto@linux.vnet.ibm.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx4/main.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
|
||||
@@ -2654,9 +2654,14 @@ static void mlx4_enable_msi_x(struct mlx
|
||||
|
||||
if (msi_x) {
|
||||
int nreq = dev->caps.num_ports * num_online_cpus() + 1;
|
||||
+ bool shared_ports = false;
|
||||
|
||||
nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
|
||||
nreq);
|
||||
+ if (nreq > MAX_MSIX) {
|
||||
+ nreq = MAX_MSIX;
|
||||
+ shared_ports = true;
|
||||
+ }
|
||||
|
||||
entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
|
||||
if (!entries)
|
||||
@@ -2679,6 +2684,9 @@ static void mlx4_enable_msi_x(struct mlx
|
||||
bitmap_zero(priv->eq_table.eq[MLX4_EQ_ASYNC].actv_ports.ports,
|
||||
dev->caps.num_ports);
|
||||
|
||||
+ if (MLX4_IS_LEGACY_EQ_MODE(dev->caps))
|
||||
+ shared_ports = true;
|
||||
+
|
||||
for (i = 0; i < dev->caps.num_comp_vectors + 1; i++) {
|
||||
if (i == MLX4_EQ_ASYNC)
|
||||
continue;
|
||||
@@ -2686,7 +2694,7 @@ static void mlx4_enable_msi_x(struct mlx
|
||||
priv->eq_table.eq[i].irq =
|
||||
entries[i + 1 - !!(i > MLX4_EQ_ASYNC)].vector;
|
||||
|
||||
- if (MLX4_IS_LEGACY_EQ_MODE(dev->caps)) {
|
||||
+ if (shared_ports) {
|
||||
bitmap_fill(priv->eq_table.eq[i].actv_ports.ports,
|
||||
dev->caps.num_ports);
|
||||
/* We don't set affinity hint when there
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Tue, 15 Sep 2015 18:29:47 -0700
|
||||
Subject: net/mlx4_en: really allow to change RSS key
|
||||
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
|
||||
[ Upsteam commit 4671fc6d47e0a0108fe24a4d830347d6a6ef4aa7 ]
|
||||
|
||||
When changing rss key, we do not want to overwrite user provided key
|
||||
by the one provided by netdev_rss_key_fill(), which is the host random
|
||||
key generated at boot time.
|
||||
|
||||
Fixes: 947cbb0ac242 ("net/mlx4_en: Support for configurable RSS hash function")
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Cc: Eyal Perry <eyalpe@mellanox.com>
|
||||
CC: Amir Vadai <amirv@mellanox.com>
|
||||
Acked-by: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
|
||||
@@ -1250,8 +1250,6 @@ int mlx4_en_config_rss_steer(struct mlx4
|
||||
rss_context->hash_fn = MLX4_RSS_HASH_TOP;
|
||||
memcpy(rss_context->rss_key, priv->rss_key,
|
||||
MLX4_EN_RSS_KEY_SIZE);
|
||||
- netdev_rss_key_fill(rss_context->rss_key,
|
||||
- MLX4_EN_RSS_KEY_SIZE);
|
||||
} else {
|
||||
en_err(priv, "Unknown RSS hash function requested\n");
|
||||
err = -EINVAL;
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Simon Guinot <simon.guinot@sequanux.org>
|
||||
Date: Tue, 15 Sep 2015 22:41:21 +0200
|
||||
Subject: net: mvneta: fix DMA buffer unmapping in mvneta_rx()
|
||||
|
||||
From: Simon Guinot <simon.guinot@sequanux.org>
|
||||
|
||||
[ Upstream commit daf158d0d544cec80b7b30deff8cfc59a6e17610 ]
|
||||
|
||||
This patch fixes a regression introduced by the commit a84e32894191
|
||||
("net: mvneta: fix refilling for Rx DMA buffers"). Due to this commit
|
||||
the newly allocated Rx buffers are DMA-unmapped in place of those passed
|
||||
to the networking stack. Obviously, this causes data corruptions.
|
||||
|
||||
This patch fixes the issue by ensuring that the right Rx buffers are
|
||||
DMA-unmapped.
|
||||
|
||||
Reported-by: Oren Laskin <oren@igneous.io>
|
||||
Signed-off-by: Simon Guinot <simon.guinot@sequanux.org>
|
||||
Fixes: a84e32894191 ("net: mvneta: fix refilling for Rx DMA buffers")
|
||||
Cc: <stable@vger.kernel.org> # v3.8+
|
||||
Tested-by: Oren Laskin <oren@igneous.io>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/marvell/mvneta.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/marvell/mvneta.c
|
||||
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
||||
@@ -1479,6 +1479,7 @@ static int mvneta_rx(struct mvneta_port
|
||||
struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
|
||||
struct sk_buff *skb;
|
||||
unsigned char *data;
|
||||
+ dma_addr_t phys_addr;
|
||||
u32 rx_status;
|
||||
int rx_bytes, err;
|
||||
|
||||
@@ -1486,6 +1487,7 @@ static int mvneta_rx(struct mvneta_port
|
||||
rx_status = rx_desc->status;
|
||||
rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
|
||||
data = (unsigned char *)rx_desc->buf_cookie;
|
||||
+ phys_addr = rx_desc->buf_phys_addr;
|
||||
|
||||
if (!mvneta_rxq_desc_is_first_last(rx_status) ||
|
||||
(rx_status & MVNETA_RXD_ERR_SUMMARY)) {
|
||||
@@ -1534,7 +1536,7 @@ static int mvneta_rx(struct mvneta_port
|
||||
if (!skb)
|
||||
goto err_drop_frame;
|
||||
|
||||
- dma_unmap_single(dev->dev.parent, rx_desc->buf_phys_addr,
|
||||
+ dma_unmap_single(dev->dev.parent, phys_addr,
|
||||
MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
|
||||
|
||||
rcvd_pkts++;
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
Date: Mon, 20 Jul 2015 17:49:56 -0700
|
||||
Subject: net: phy: fixed_phy: handle link-down case
|
||||
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
|
||||
[ Upstream 868a4215be9a6d80548ccb74763b883dc99d32a2 in net-next tree,
|
||||
will be pushed to Linus very soon. ]
|
||||
|
||||
fixed_phy_register() currently hardcodes the fixed PHY link to 1, and
|
||||
expects to find a "speed" parameter to provide correct information
|
||||
towards the fixed PHY consumer.
|
||||
|
||||
In a subsequent change, where we allow "managed" (e.g: (RS)GMII in-band
|
||||
status auto-negotiation) fixed PHYs, none of these parameters can be
|
||||
provided since they will be auto-negotiated, hence, we just provide a
|
||||
zero-initialized fixed_phy_status to fixed_phy_register() which makes it
|
||||
fail when we call fixed_phy_update_regs() since status.speed = 0 which
|
||||
makes us hit the "default" label and error out.
|
||||
|
||||
Without this change, we would also see potentially inconsistent
|
||||
speed/duplex parameters for fixed PHYs when the link is DOWN.
|
||||
|
||||
CC: netdev@vger.kernel.org
|
||||
CC: linux-kernel@vger.kernel.org
|
||||
Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
|
||||
[florian: add more background to why this is correct and desirable]
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/phy/fixed_phy.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/fixed_phy.c
|
||||
+++ b/drivers/net/phy/fixed_phy.c
|
||||
@@ -52,6 +52,10 @@ static int fixed_phy_update_regs(struct
|
||||
u16 lpagb = 0;
|
||||
u16 lpa = 0;
|
||||
|
||||
+ if (!fp->status.link)
|
||||
+ goto done;
|
||||
+ bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
|
||||
+
|
||||
if (fp->status.duplex) {
|
||||
bmcr |= BMCR_FULLDPLX;
|
||||
|
||||
@@ -96,15 +100,13 @@ static int fixed_phy_update_regs(struct
|
||||
}
|
||||
}
|
||||
|
||||
- if (fp->status.link)
|
||||
- bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
|
||||
-
|
||||
if (fp->status.pause)
|
||||
lpa |= LPA_PAUSE_CAP;
|
||||
|
||||
if (fp->status.asym_pause)
|
||||
lpa |= LPA_PAUSE_ASYM;
|
||||
|
||||
+done:
|
||||
fp->regs[MII_PHYSID1] = 0;
|
||||
fp->regs[MII_PHYSID2] = 0;
|
||||
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
Date: Tue, 22 Sep 2015 17:01:11 -0700
|
||||
Subject: net: revert "net_sched: move tp->root allocation into fw_init()"
|
||||
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
|
||||
[ Upstream commit d8aecb10115497f6cdf841df8c88ebb3ba25fa28 ]
|
||||
|
||||
fw filter uses tp->root==NULL to check if it is the old method,
|
||||
so it doesn't need allocation at all in this case. This patch
|
||||
reverts the offending commit and adds some comments for old
|
||||
method to make it obvious.
|
||||
|
||||
Fixes: 33f8b9ecdb15 ("net_sched: move tp->root allocation into fw_init()")
|
||||
Reported-by: Akshat Kakkar <akshat.1984@gmail.com>
|
||||
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
|
||||
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/sched/cls_fw.c | 30 +++++++++++++++---------------
|
||||
1 file changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/net/sched/cls_fw.c
|
||||
+++ b/net/sched/cls_fw.c
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
struct fw_head {
|
||||
u32 mask;
|
||||
- bool mask_set;
|
||||
struct fw_filter __rcu *ht[HTSIZE];
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
@@ -84,7 +83,7 @@ static int fw_classify(struct sk_buff *s
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- /* old method */
|
||||
+ /* Old method: classify the packet using its skb mark. */
|
||||
if (id && (TC_H_MAJ(id) == 0 ||
|
||||
!(TC_H_MAJ(id ^ tp->q->handle)))) {
|
||||
res->classid = id;
|
||||
@@ -114,14 +113,9 @@ static unsigned long fw_get(struct tcf_p
|
||||
|
||||
static int fw_init(struct tcf_proto *tp)
|
||||
{
|
||||
- struct fw_head *head;
|
||||
-
|
||||
- head = kzalloc(sizeof(struct fw_head), GFP_KERNEL);
|
||||
- if (head == NULL)
|
||||
- return -ENOBUFS;
|
||||
-
|
||||
- head->mask_set = false;
|
||||
- rcu_assign_pointer(tp->root, head);
|
||||
+ /* We don't allocate fw_head here, because in the old method
|
||||
+ * we don't need it at all.
|
||||
+ */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -252,7 +246,7 @@ static int fw_change(struct net *net, st
|
||||
int err;
|
||||
|
||||
if (!opt)
|
||||
- return handle ? -EINVAL : 0;
|
||||
+ return handle ? -EINVAL : 0; /* Succeed if it is old method. */
|
||||
|
||||
err = nla_parse_nested(tb, TCA_FW_MAX, opt, fw_policy);
|
||||
if (err < 0)
|
||||
@@ -302,11 +296,17 @@ static int fw_change(struct net *net, st
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
- if (!head->mask_set) {
|
||||
- head->mask = 0xFFFFFFFF;
|
||||
+ if (!head) {
|
||||
+ u32 mask = 0xFFFFFFFF;
|
||||
if (tb[TCA_FW_MASK])
|
||||
- head->mask = nla_get_u32(tb[TCA_FW_MASK]);
|
||||
- head->mask_set = true;
|
||||
+ mask = nla_get_u32(tb[TCA_FW_MASK]);
|
||||
+
|
||||
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
|
||||
+ if (!head)
|
||||
+ return -ENOBUFS;
|
||||
+ head->mask = mask;
|
||||
+
|
||||
+ rcu_assign_pointer(tp->root, head);
|
||||
}
|
||||
|
||||
f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL);
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Fri, 18 Sep 2015 19:16:50 +0800
|
||||
Subject: netlink: Fix autobind race condition that leads to zero port ID
|
||||
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
[ Upstream commit 1f770c0a09da855a2b51af6d19de97fb955eca85 ]
|
||||
|
||||
The commit c0bb07df7d981e4091432754e30c9c720e2c0c78 ("netlink:
|
||||
Reset portid after netlink_insert failure") introduced a race
|
||||
condition where if two threads try to autobind the same socket
|
||||
one of them may end up with a zero port ID. This led to kernel
|
||||
deadlocks that were observed by multiple people.
|
||||
|
||||
This patch reverts that commit and instead fixes it by introducing
|
||||
a separte rhash_portid variable so that the real portid is only set
|
||||
after the socket has been successfully hashed.
|
||||
|
||||
Fixes: c0bb07df7d98 ("netlink: Reset portid after netlink_insert failure")
|
||||
Reported-by: Tejun Heo <tj@kernel.org>
|
||||
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/netlink/af_netlink.c | 12 +++++++-----
|
||||
net/netlink/af_netlink.h | 1 +
|
||||
2 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -1019,7 +1019,7 @@ static inline int netlink_compare(struct
|
||||
const struct netlink_compare_arg *x = arg->key;
|
||||
const struct netlink_sock *nlk = ptr;
|
||||
|
||||
- return nlk->portid != x->portid ||
|
||||
+ return nlk->rhash_portid != x->portid ||
|
||||
!net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
|
||||
}
|
||||
|
||||
@@ -1045,7 +1045,7 @@ static int __netlink_insert(struct netli
|
||||
{
|
||||
struct netlink_compare_arg arg;
|
||||
|
||||
- netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->portid);
|
||||
+ netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->rhash_portid);
|
||||
return rhashtable_lookup_insert_key(&table->hash, &arg,
|
||||
&nlk_sk(sk)->node,
|
||||
netlink_rhashtable_params);
|
||||
@@ -1107,7 +1107,7 @@ static int netlink_insert(struct sock *s
|
||||
unlikely(atomic_read(&table->hash.nelems) >= UINT_MAX))
|
||||
goto err;
|
||||
|
||||
- nlk_sk(sk)->portid = portid;
|
||||
+ nlk_sk(sk)->rhash_portid = portid;
|
||||
sock_hold(sk);
|
||||
|
||||
err = __netlink_insert(table, sk);
|
||||
@@ -1119,10 +1119,12 @@ static int netlink_insert(struct sock *s
|
||||
err = -EOVERFLOW;
|
||||
if (err == -EEXIST)
|
||||
err = -EADDRINUSE;
|
||||
- nlk_sk(sk)->portid = 0;
|
||||
sock_put(sk);
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
+ nlk_sk(sk)->portid = portid;
|
||||
+
|
||||
err:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
@@ -3233,7 +3235,7 @@ static inline u32 netlink_hash(const voi
|
||||
const struct netlink_sock *nlk = data;
|
||||
struct netlink_compare_arg arg;
|
||||
|
||||
- netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
|
||||
+ netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->rhash_portid);
|
||||
return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
|
||||
}
|
||||
|
||||
--- a/net/netlink/af_netlink.h
|
||||
+++ b/net/netlink/af_netlink.h
|
||||
@@ -25,6 +25,7 @@ struct netlink_ring {
|
||||
struct netlink_sock {
|
||||
/* struct sock has to be the first member of netlink_sock */
|
||||
struct sock sk;
|
||||
+ u32 rhash_portid;
|
||||
u32 portid;
|
||||
u32 dst_portid;
|
||||
u32 dst_group;
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Date: Thu, 10 Sep 2015 20:05:46 +0200
|
||||
Subject: netlink, mmap: transform mmap skb into full skb on taps
|
||||
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
|
||||
[ Upstream commit 1853c949646005b5959c483becde86608f548f24 ]
|
||||
|
||||
Ken-ichirou reported that running netlink in mmap mode for receive in
|
||||
combination with nlmon will throw a NULL pointer dereference in
|
||||
__kfree_skb() on nlmon_xmit(), in my case I can also trigger an "unable
|
||||
to handle kernel paging request". The problem is the skb_clone() in
|
||||
__netlink_deliver_tap_skb() for skbs that are mmaped.
|
||||
|
||||
I.e. the cloned skb doesn't have a destructor, whereas the mmap netlink
|
||||
skb has it pointed to netlink_skb_destructor(), set in the handler
|
||||
netlink_ring_setup_skb(). There, skb->head is being set to NULL, so
|
||||
that in such cases, __kfree_skb() doesn't perform a skb_release_data()
|
||||
via skb_release_all(), where skb->head is possibly being freed through
|
||||
kfree(head) into slab allocator, although netlink mmap skb->head points
|
||||
to the mmap buffer. Similarly, the same has to be done also for large
|
||||
netlink skbs where the data area is vmalloced. Therefore, as discussed,
|
||||
make a copy for these rather rare cases for now. This fixes the issue
|
||||
on my and Ken-ichirou's test-cases.
|
||||
|
||||
Reference: http://thread.gmane.org/gmane.linux.network/371129
|
||||
Fixes: bcbde0d449ed ("net: netlink: virtual tap device management")
|
||||
Reported-by: Ken-ichirou MATSUZAWA <chamaken@gmail.com>
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Tested-by: Ken-ichirou MATSUZAWA <chamaken@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/netlink/af_netlink.c | 30 +++++++++++++++++++++++-------
|
||||
net/netlink/af_netlink.h | 9 +++++++++
|
||||
2 files changed, 32 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -124,6 +124,24 @@ static inline u32 netlink_group_mask(u32
|
||||
return group ? 1 << (group - 1) : 0;
|
||||
}
|
||||
|
||||
+static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
|
||||
+ gfp_t gfp_mask)
|
||||
+{
|
||||
+ unsigned int len = skb_end_offset(skb);
|
||||
+ struct sk_buff *new;
|
||||
+
|
||||
+ new = alloc_skb(len, gfp_mask);
|
||||
+ if (new == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ NETLINK_CB(new).portid = NETLINK_CB(skb).portid;
|
||||
+ NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group;
|
||||
+ NETLINK_CB(new).creds = NETLINK_CB(skb).creds;
|
||||
+
|
||||
+ memcpy(skb_put(new, len), skb->data, len);
|
||||
+ return new;
|
||||
+}
|
||||
+
|
||||
int netlink_add_tap(struct netlink_tap *nt)
|
||||
{
|
||||
if (unlikely(nt->dev->type != ARPHRD_NETLINK))
|
||||
@@ -205,7 +223,11 @@ static int __netlink_deliver_tap_skb(str
|
||||
int ret = -ENOMEM;
|
||||
|
||||
dev_hold(dev);
|
||||
- nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
+
|
||||
+ if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head))
|
||||
+ nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
|
||||
+ else
|
||||
+ nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (nskb) {
|
||||
nskb->dev = dev;
|
||||
nskb->protocol = htons((u16) sk->sk_protocol);
|
||||
@@ -278,11 +300,6 @@ static void netlink_rcv_wake(struct sock
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETLINK_MMAP
|
||||
-static bool netlink_skb_is_mmaped(const struct sk_buff *skb)
|
||||
-{
|
||||
- return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
|
||||
-}
|
||||
-
|
||||
static bool netlink_rx_is_mmaped(struct sock *sk)
|
||||
{
|
||||
return nlk_sk(sk)->rx_ring.pg_vec != NULL;
|
||||
@@ -834,7 +851,6 @@ static void netlink_ring_set_copied(stru
|
||||
}
|
||||
|
||||
#else /* CONFIG_NETLINK_MMAP */
|
||||
-#define netlink_skb_is_mmaped(skb) false
|
||||
#define netlink_rx_is_mmaped(sk) false
|
||||
#define netlink_tx_is_mmaped(sk) false
|
||||
#define netlink_mmap sock_no_mmap
|
||||
--- a/net/netlink/af_netlink.h
|
||||
+++ b/net/netlink/af_netlink.h
|
||||
@@ -59,6 +59,15 @@ static inline struct netlink_sock *nlk_s
|
||||
return container_of(sk, struct netlink_sock, sk);
|
||||
}
|
||||
|
||||
+static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb)
|
||||
+{
|
||||
+#ifdef CONFIG_NETLINK_MMAP
|
||||
+ return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif /* CONFIG_NETLINK_MMAP */
|
||||
+}
|
||||
+
|
||||
struct netlink_table {
|
||||
struct rhashtable hash;
|
||||
struct hlist_head mc_list;
|
||||
-245
@@ -1,245 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Tue, 22 Sep 2015 11:38:56 +0800
|
||||
Subject: netlink: Replace rhash_portid with bound
|
||||
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
[ Upstream commit da314c9923fed553a007785a901fd395b7eb6c19 ]
|
||||
|
||||
On Mon, Sep 21, 2015 at 02:20:22PM -0400, Tejun Heo wrote:
|
||||
>
|
||||
> store_release and load_acquire are different from the usual memory
|
||||
> barriers and can't be paired this way. You have to pair store_release
|
||||
> and load_acquire. Besides, it isn't a particularly good idea to
|
||||
|
||||
OK I've decided to drop the acquire/release helpers as they don't
|
||||
help us at all and simply pessimises the code by using full memory
|
||||
barriers (on some architectures) where only a write or read barrier
|
||||
is needed.
|
||||
|
||||
> depend on memory barriers embedded in other data structures like the
|
||||
> above. Here, especially, rhashtable_insert() would have write barrier
|
||||
> *before* the entry is hashed not necessarily *after*, which means that
|
||||
> in the above case, a socket which appears to have set bound to a
|
||||
> reader might not visible when the reader tries to look up the socket
|
||||
> on the hashtable.
|
||||
|
||||
But you are right we do need an explicit write barrier here to
|
||||
ensure that the hashing is visible.
|
||||
|
||||
> There's no reason to be overly smart here. This isn't a crazy hot
|
||||
> path, write barriers tend to be very cheap, store_release more so.
|
||||
> Please just do smp_store_release() and note what it's paired with.
|
||||
|
||||
It's not about being overly smart. It's about actually understanding
|
||||
what's going on with the code. I've seen too many instances of
|
||||
people simply sprinkling synchronisation primitives around without
|
||||
any knowledge of what is happening underneath, which is just a recipe
|
||||
for creating hard-to-debug races.
|
||||
|
||||
> > @@ -1539,7 +1546,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
||||
> > }
|
||||
> > }
|
||||
> >
|
||||
> > - if (!nlk->portid) {
|
||||
> > + if (!nlk->bound) {
|
||||
>
|
||||
> I don't think you can skip load_acquire here just because this is the
|
||||
> second deref of the variable. That doesn't change anything. Race
|
||||
> condition could still happen between the first and second tests and
|
||||
> skipping the second would lead to the same kind of bug.
|
||||
|
||||
The reason this one is OK is because we do not use nlk->portid or
|
||||
try to get nlk from the hash table before we return to user-space.
|
||||
|
||||
However, there is a real bug here that none of these acquire/release
|
||||
helpers discovered. The two bound tests here used to be a single
|
||||
one. Now that they are separate it is entirely possible for another
|
||||
thread to come in the middle and bind the socket. So we need to
|
||||
repeat the portid check in order to maintain consistency.
|
||||
|
||||
> > @@ -1587,7 +1594,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
|
||||
> > !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
||||
> > return -EPERM;
|
||||
> >
|
||||
> > - if (!nlk->portid)
|
||||
> > + if (!nlk->bound)
|
||||
>
|
||||
> Don't we need load_acquire here too? Is this path holding a lock
|
||||
> which makes that unnecessary?
|
||||
|
||||
Ditto.
|
||||
|
||||
---8<---
|
||||
The commit 1f770c0a09da855a2b51af6d19de97fb955eca85 ("netlink:
|
||||
Fix autobind race condition that leads to zero port ID") created
|
||||
some new races that can occur due to inconcsistencies between the
|
||||
two port IDs.
|
||||
|
||||
Tejun is right that a barrier is unavoidable. Therefore I am
|
||||
reverting to the original patch that used a boolean to indicate
|
||||
that a user netlink socket has been bound.
|
||||
|
||||
Barriers have been added where necessary to ensure that a valid
|
||||
portid and the hashed socket is visible.
|
||||
|
||||
I have also changed netlink_insert to only return EBUSY if the
|
||||
socket is bound to a portid different to the requested one. This
|
||||
combined with only reading nlk->bound once in netlink_bind fixes
|
||||
a race where two threads that bind the socket at the same time
|
||||
with different port IDs may both succeed.
|
||||
|
||||
Fixes: 1f770c0a09da ("netlink: Fix autobind race condition that leads to zero port ID")
|
||||
Reported-by: Tejun Heo <tj@kernel.org>
|
||||
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Nacked-by: Tejun Heo <tj@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/netlink/af_netlink.c | 39 ++++++++++++++++++++++++++++-----------
|
||||
net/netlink/af_netlink.h | 2 +-
|
||||
2 files changed, 29 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -1019,7 +1019,7 @@ static inline int netlink_compare(struct
|
||||
const struct netlink_compare_arg *x = arg->key;
|
||||
const struct netlink_sock *nlk = ptr;
|
||||
|
||||
- return nlk->rhash_portid != x->portid ||
|
||||
+ return nlk->portid != x->portid ||
|
||||
!net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
|
||||
}
|
||||
|
||||
@@ -1045,7 +1045,7 @@ static int __netlink_insert(struct netli
|
||||
{
|
||||
struct netlink_compare_arg arg;
|
||||
|
||||
- netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->rhash_portid);
|
||||
+ netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->portid);
|
||||
return rhashtable_lookup_insert_key(&table->hash, &arg,
|
||||
&nlk_sk(sk)->node,
|
||||
netlink_rhashtable_params);
|
||||
@@ -1098,8 +1098,8 @@ static int netlink_insert(struct sock *s
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
- err = -EBUSY;
|
||||
- if (nlk_sk(sk)->portid)
|
||||
+ err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY;
|
||||
+ if (nlk_sk(sk)->bound)
|
||||
goto err;
|
||||
|
||||
err = -ENOMEM;
|
||||
@@ -1107,7 +1107,7 @@ static int netlink_insert(struct sock *s
|
||||
unlikely(atomic_read(&table->hash.nelems) >= UINT_MAX))
|
||||
goto err;
|
||||
|
||||
- nlk_sk(sk)->rhash_portid = portid;
|
||||
+ nlk_sk(sk)->portid = portid;
|
||||
sock_hold(sk);
|
||||
|
||||
err = __netlink_insert(table, sk);
|
||||
@@ -1123,7 +1123,9 @@ static int netlink_insert(struct sock *s
|
||||
goto err;
|
||||
}
|
||||
|
||||
- nlk_sk(sk)->portid = portid;
|
||||
+ /* We need to ensure that the socket is hashed and visible. */
|
||||
+ smp_wmb();
|
||||
+ nlk_sk(sk)->bound = portid;
|
||||
|
||||
err:
|
||||
release_sock(sk);
|
||||
@@ -1509,6 +1511,7 @@ static int netlink_bind(struct socket *s
|
||||
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
|
||||
int err;
|
||||
long unsigned int groups = nladdr->nl_groups;
|
||||
+ bool bound;
|
||||
|
||||
if (addr_len < sizeof(struct sockaddr_nl))
|
||||
return -EINVAL;
|
||||
@@ -1525,9 +1528,14 @@ static int netlink_bind(struct socket *s
|
||||
return err;
|
||||
}
|
||||
|
||||
- if (nlk->portid)
|
||||
+ bound = nlk->bound;
|
||||
+ if (bound) {
|
||||
+ /* Ensure nlk->portid is up-to-date. */
|
||||
+ smp_rmb();
|
||||
+
|
||||
if (nladdr->nl_pid != nlk->portid)
|
||||
return -EINVAL;
|
||||
+ }
|
||||
|
||||
if (nlk->netlink_bind && groups) {
|
||||
int group;
|
||||
@@ -1543,7 +1551,10 @@ static int netlink_bind(struct socket *s
|
||||
}
|
||||
}
|
||||
|
||||
- if (!nlk->portid) {
|
||||
+ /* No need for barriers here as we return to user-space without
|
||||
+ * using any of the bound attributes.
|
||||
+ */
|
||||
+ if (!bound) {
|
||||
err = nladdr->nl_pid ?
|
||||
netlink_insert(sk, nladdr->nl_pid) :
|
||||
netlink_autobind(sock);
|
||||
@@ -1591,7 +1602,10 @@ static int netlink_connect(struct socket
|
||||
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
||||
return -EPERM;
|
||||
|
||||
- if (!nlk->portid)
|
||||
+ /* No need for barriers here as we return to user-space without
|
||||
+ * using any of the bound attributes.
|
||||
+ */
|
||||
+ if (!nlk->bound)
|
||||
err = netlink_autobind(sock);
|
||||
|
||||
if (err == 0) {
|
||||
@@ -2409,10 +2423,13 @@ static int netlink_sendmsg(struct socket
|
||||
dst_group = nlk->dst_group;
|
||||
}
|
||||
|
||||
- if (!nlk->portid) {
|
||||
+ if (!nlk->bound) {
|
||||
err = netlink_autobind(sock);
|
||||
if (err)
|
||||
goto out;
|
||||
+ } else {
|
||||
+ /* Ensure nlk is hashed and visible. */
|
||||
+ smp_rmb();
|
||||
}
|
||||
|
||||
/* It's a really convoluted way for userland to ask for mmaped
|
||||
@@ -3235,7 +3252,7 @@ static inline u32 netlink_hash(const voi
|
||||
const struct netlink_sock *nlk = data;
|
||||
struct netlink_compare_arg arg;
|
||||
|
||||
- netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->rhash_portid);
|
||||
+ netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
|
||||
return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
|
||||
}
|
||||
|
||||
--- a/net/netlink/af_netlink.h
|
||||
+++ b/net/netlink/af_netlink.h
|
||||
@@ -25,7 +25,6 @@ struct netlink_ring {
|
||||
struct netlink_sock {
|
||||
/* struct sock has to be the first member of netlink_sock */
|
||||
struct sock sk;
|
||||
- u32 rhash_portid;
|
||||
u32 portid;
|
||||
u32 dst_portid;
|
||||
u32 dst_group;
|
||||
@@ -36,6 +35,7 @@ struct netlink_sock {
|
||||
unsigned long state;
|
||||
size_t max_recvmsg_len;
|
||||
wait_queue_head_t wait;
|
||||
+ bool bound;
|
||||
bool cb_running;
|
||||
struct netlink_callback cb;
|
||||
struct mutex *cb_mutex;
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
Date: Mon, 20 Jul 2015 17:49:57 -0700
|
||||
Subject: of_mdio: add new DT property 'managed' to specify the PHY management type
|
||||
|
||||
From: Stas Sergeev <stsp@list.ru>
|
||||
|
||||
[ Upstream commit 4cba5c2103657d43d0886e4cff8004d95a3d0def in net-next tree,
|
||||
will be pushed to Linus very soon. ]
|
||||
|
||||
Currently the PHY management type is selected by the MAC driver arbitrary.
|
||||
The decision is based on the presence of the "fixed-link" node and on a
|
||||
will of the driver's authors.
|
||||
This caused a regression recently, when mvneta driver suddenly started
|
||||
to use the in-band status for auto-negotiation on fixed links.
|
||||
It appears the auto-negotiation may not work when expected by the MAC driver.
|
||||
Sebastien Rannou explains:
|
||||
<< Yes, I confirm that my HW does not generate an in-band status. AFAIK, it's
|
||||
a PHY that aggregates 4xSGMIIs to 1xQSGMII ; the MAC side of the PHY (with
|
||||
inband status) is connected to the switch through QSGMII, and in this context
|
||||
we are on the media side of the PHY. >>
|
||||
https://lkml.org/lkml/2015/7/10/206
|
||||
|
||||
This patch introduces the new string property 'managed' that allows
|
||||
the user to set the management type explicitly.
|
||||
The supported values are:
|
||||
"auto" - default. Uses either MDIO or nothing, depending on the presence
|
||||
of the fixed-link node
|
||||
"in-band-status" - use in-band status
|
||||
|
||||
Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
|
||||
|
||||
CC: Rob Herring <robh+dt@kernel.org>
|
||||
CC: Pawel Moll <pawel.moll@arm.com>
|
||||
CC: Mark Rutland <mark.rutland@arm.com>
|
||||
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
|
||||
CC: Kumar Gala <galak@codeaurora.org>
|
||||
CC: Florian Fainelli <f.fainelli@gmail.com>
|
||||
CC: Grant Likely <grant.likely@linaro.org>
|
||||
CC: devicetree@vger.kernel.org
|
||||
CC: linux-kernel@vger.kernel.org
|
||||
CC: netdev@vger.kernel.org
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/net/ethernet.txt | 4 ++++
|
||||
drivers/of/of_mdio.c | 19 +++++++++++++++++--
|
||||
2 files changed, 21 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/ethernet.txt
|
||||
+++ b/Documentation/devicetree/bindings/net/ethernet.txt
|
||||
@@ -25,7 +25,11 @@ The following properties are common to t
|
||||
flow control thresholds.
|
||||
- tx-fifo-depth: the size of the controller's transmit fifo in bytes. This
|
||||
is used for components that can have configurable fifo sizes.
|
||||
+- managed: string, specifies the PHY management type. Supported values are:
|
||||
+ "auto", "in-band-status". "auto" is the default, it usess MDIO for
|
||||
+ management if fixed-link is not specified.
|
||||
|
||||
Child nodes of the Ethernet controller are typically the individual PHY devices
|
||||
connected via the MDIO bus (sometimes the MDIO bus controller is separate).
|
||||
They are described in the phy.txt file in this same directory.
|
||||
+For non-MDIO PHY management see fixed-link.txt.
|
||||
--- a/drivers/of/of_mdio.c
|
||||
+++ b/drivers/of/of_mdio.c
|
||||
@@ -266,7 +266,8 @@ EXPORT_SYMBOL(of_phy_attach);
|
||||
bool of_phy_is_fixed_link(struct device_node *np)
|
||||
{
|
||||
struct device_node *dn;
|
||||
- int len;
|
||||
+ int len, err;
|
||||
+ const char *managed;
|
||||
|
||||
/* New binding */
|
||||
dn = of_get_child_by_name(np, "fixed-link");
|
||||
@@ -275,6 +276,10 @@ bool of_phy_is_fixed_link(struct device_
|
||||
return true;
|
||||
}
|
||||
|
||||
+ err = of_property_read_string(np, "managed", &managed);
|
||||
+ if (err == 0 && strcmp(managed, "auto") != 0)
|
||||
+ return true;
|
||||
+
|
||||
/* Old binding */
|
||||
if (of_get_property(np, "fixed-link", &len) &&
|
||||
len == (5 * sizeof(__be32)))
|
||||
@@ -289,8 +294,18 @@ int of_phy_register_fixed_link(struct de
|
||||
struct fixed_phy_status status = {};
|
||||
struct device_node *fixed_link_node;
|
||||
const __be32 *fixed_link_prop;
|
||||
- int len;
|
||||
+ int len, err;
|
||||
struct phy_device *phy;
|
||||
+ const char *managed;
|
||||
+
|
||||
+ err = of_property_read_string(np, "managed", &managed);
|
||||
+ if (err == 0) {
|
||||
+ if (strcmp(managed, "in-band-status") == 0) {
|
||||
+ /* status is zeroed, namely its .link member */
|
||||
+ phy = fixed_phy_register(PHY_POLL, &status, np);
|
||||
+ return IS_ERR(phy) ? PTR_ERR(phy) : 0;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* New binding */
|
||||
fixed_link_node = of_get_child_by_name(np, "fixed-link");
|
||||
@@ -1,116 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Jesse Gross <jesse@nicira.com>
|
||||
Date: Mon, 21 Sep 2015 20:21:20 -0700
|
||||
Subject: openvswitch: Zero flows on allocation.
|
||||
|
||||
From: Jesse Gross <jesse@nicira.com>
|
||||
|
||||
[ Upstream commit ae5f2fb1d51fa128a460bcfbe3c56d7ab8bf6a43 ]
|
||||
|
||||
When support for megaflows was introduced, OVS needed to start
|
||||
installing flows with a mask applied to them. Since masking is an
|
||||
expensive operation, OVS also had an optimization that would only
|
||||
take the parts of the flow keys that were covered by a non-zero
|
||||
mask. The values stored in the remaining pieces should not matter
|
||||
because they are masked out.
|
||||
|
||||
While this works fine for the purposes of matching (which must always
|
||||
look at the mask), serialization to netlink can be problematic. Since
|
||||
the flow and the mask are serialized separately, the uninitialized
|
||||
portions of the flow can be encoded with whatever values happen to be
|
||||
present.
|
||||
|
||||
In terms of functionality, this has little effect since these fields
|
||||
will be masked out by definition. However, it leaks kernel memory to
|
||||
userspace, which is a potential security vulnerability. It is also
|
||||
possible that other code paths could look at the masked key and get
|
||||
uninitialized data, although this does not currently appear to be an
|
||||
issue in practice.
|
||||
|
||||
This removes the mask optimization for flows that are being installed.
|
||||
This was always intended to be the case as the mask optimizations were
|
||||
really targetting per-packet flow operations.
|
||||
|
||||
Fixes: 03f0d916 ("openvswitch: Mega flow implementation")
|
||||
Signed-off-by: Jesse Gross <jesse@nicira.com>
|
||||
Acked-by: Pravin B Shelar <pshelar@nicira.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/openvswitch/datapath.c | 4 ++--
|
||||
net/openvswitch/flow_table.c | 23 ++++++++++++-----------
|
||||
net/openvswitch/flow_table.h | 2 +-
|
||||
3 files changed, 15 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/net/openvswitch/datapath.c
|
||||
+++ b/net/openvswitch/datapath.c
|
||||
@@ -920,7 +920,7 @@ static int ovs_flow_cmd_new(struct sk_bu
|
||||
if (error)
|
||||
goto err_kfree_flow;
|
||||
|
||||
- ovs_flow_mask_key(&new_flow->key, &key, &mask);
|
||||
+ ovs_flow_mask_key(&new_flow->key, &key, true, &mask);
|
||||
|
||||
/* Extract flow identifier. */
|
||||
error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
|
||||
@@ -1047,7 +1047,7 @@ static struct sw_flow_actions *get_flow_
|
||||
struct sw_flow_key masked_key;
|
||||
int error;
|
||||
|
||||
- ovs_flow_mask_key(&masked_key, key, mask);
|
||||
+ ovs_flow_mask_key(&masked_key, key, true, mask);
|
||||
error = ovs_nla_copy_actions(a, &masked_key, &acts, log);
|
||||
if (error) {
|
||||
OVS_NLERR(log,
|
||||
--- a/net/openvswitch/flow_table.c
|
||||
+++ b/net/openvswitch/flow_table.c
|
||||
@@ -56,20 +56,21 @@ static u16 range_n_bytes(const struct sw
|
||||
}
|
||||
|
||||
void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
|
||||
- const struct sw_flow_mask *mask)
|
||||
+ bool full, const struct sw_flow_mask *mask)
|
||||
{
|
||||
- const long *m = (const long *)((const u8 *)&mask->key +
|
||||
- mask->range.start);
|
||||
- const long *s = (const long *)((const u8 *)src +
|
||||
- mask->range.start);
|
||||
- long *d = (long *)((u8 *)dst + mask->range.start);
|
||||
+ int start = full ? 0 : mask->range.start;
|
||||
+ int len = full ? sizeof *dst : range_n_bytes(&mask->range);
|
||||
+ const long *m = (const long *)((const u8 *)&mask->key + start);
|
||||
+ const long *s = (const long *)((const u8 *)src + start);
|
||||
+ long *d = (long *)((u8 *)dst + start);
|
||||
int i;
|
||||
|
||||
- /* The memory outside of the 'mask->range' are not set since
|
||||
- * further operations on 'dst' only uses contents within
|
||||
- * 'mask->range'.
|
||||
+ /* If 'full' is true then all of 'dst' is fully initialized. Otherwise,
|
||||
+ * if 'full' is false the memory outside of the 'mask->range' is left
|
||||
+ * uninitialized. This can be used as an optimization when further
|
||||
+ * operations on 'dst' only use contents within 'mask->range'.
|
||||
*/
|
||||
- for (i = 0; i < range_n_bytes(&mask->range); i += sizeof(long))
|
||||
+ for (i = 0; i < len; i += sizeof(long))
|
||||
*d++ = *s++ & *m++;
|
||||
}
|
||||
|
||||
@@ -473,7 +474,7 @@ static struct sw_flow *masked_flow_looku
|
||||
u32 hash;
|
||||
struct sw_flow_key masked_key;
|
||||
|
||||
- ovs_flow_mask_key(&masked_key, unmasked, mask);
|
||||
+ ovs_flow_mask_key(&masked_key, unmasked, false, mask);
|
||||
hash = flow_hash(&masked_key, &mask->range);
|
||||
head = find_bucket(ti, hash);
|
||||
hlist_for_each_entry_rcu(flow, head, flow_table.node[ti->node_ver]) {
|
||||
--- a/net/openvswitch/flow_table.h
|
||||
+++ b/net/openvswitch/flow_table.h
|
||||
@@ -86,5 +86,5 @@ struct sw_flow *ovs_flow_tbl_lookup_ufid
|
||||
bool ovs_flow_cmp(const struct sw_flow *, const struct sw_flow_match *);
|
||||
|
||||
void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
|
||||
- const struct sw_flow_mask *mask);
|
||||
+ bool full, const struct sw_flow_mask *mask);
|
||||
#endif /* flow_table.h */
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Mark Salter <msalter@redhat.com>
|
||||
Date: Tue, 1 Sep 2015 09:36:05 -0400
|
||||
Subject: phylib: fix device deletion order in mdiobus_unregister()
|
||||
|
||||
From: Mark Salter <msalter@redhat.com>
|
||||
|
||||
[ Upstream commit b6c6aedcbcbacd7b0cb4b64ed5ac835bc1c60a03 ]
|
||||
|
||||
commit 8b63ec1837fa ("phylib: Make PHYs children of their MDIO bus, not
|
||||
the bus' parent.") uncovered a problem in mdiobus_unregister() which
|
||||
leads to this warning when I reboot an APM Mustang (arm64) platform:
|
||||
|
||||
WARNING: CPU: 7 PID: 4239 at fs/sysfs/group.c:224 sysfs_remove_group+0xa0/0xa4()
|
||||
sysfs group fffffe0000e07a10 not found for kobject 'xgene-mii-eth0:03'
|
||||
...
|
||||
CPU: 7 PID: 4239 Comm: reboot Tainted: G E 4.2.0-0.18.el7.test15.aarch64 #1
|
||||
Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0 Aug 26 2015
|
||||
Call Trace:
|
||||
[<fffffe000009739c>] dump_backtrace+0x0/0x170
|
||||
[<fffffe000009752c>] show_stack+0x20/0x2c
|
||||
[<fffffe00007436f0>] dump_stack+0x78/0x9c
|
||||
[<fffffe00000c2cb4>] warn_slowpath_common+0xa0/0xd8
|
||||
[<fffffe00000c2d60>] warn_slowpath_fmt+0x74/0x88
|
||||
[<fffffe0000293d3c>] sysfs_remove_group+0x9c/0xa4
|
||||
[<fffffe00004a8bac>] dpm_sysfs_remove+0x5c/0x70
|
||||
[<fffffe000049b388>] device_del+0x44/0x208
|
||||
[<fffffe000049b578>] device_unregister+0x2c/0x7c
|
||||
[<fffffe000050dc68>] mdiobus_unregister+0x48/0x94
|
||||
[<fffffe000052afd0>] xgene_enet_mdio_remove+0x28/0x44
|
||||
[<fffffe000052d3f0>] xgene_enet_remove+0xd0/0xd8
|
||||
[<fffffe000052d424>] xgene_enet_shutdown+0x2c/0x3c
|
||||
[<fffffe00004a204c>] platform_drv_shutdown+0x24/0x40
|
||||
[<fffffe000049d4f4>] device_shutdown+0xf0/0x1b4
|
||||
[<fffffe00000e31ec>] kernel_restart_prepare+0x40/0x4c
|
||||
[<fffffe00000e32f8>] kernel_restart+0x1c/0x80
|
||||
[<fffffe00000e3670>] SyS_reboot+0x17c/0x250
|
||||
|
||||
The problem is that mdiobus_unregister() deletes the bus device before
|
||||
unregistering the phy devices on the bus. This wasn't a problem before
|
||||
because the phys were not children of the bus:
|
||||
|
||||
/sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0:03
|
||||
/sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0
|
||||
|
||||
But now that they are:
|
||||
|
||||
/sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0/xgene-mii-eth0:03
|
||||
|
||||
when mdiobus_unregister deletes the bus device, the phy subdirs are
|
||||
removed from sysfs also. So when the phys are unregistered afterward,
|
||||
we get the warning. This patch changes the order so that phys are
|
||||
unregistered before the bus device is deleted.
|
||||
|
||||
Fixes: 8b63ec1837fa ("phylib: Make PHYs children of their MDIO bus, not the bus' parent.")
|
||||
Signed-off-by: Mark Salter <msalter@redhat.com>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Tested-by: Mark Langsdorf <mlangsdo@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/phy/mdio_bus.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/mdio_bus.c
|
||||
+++ b/drivers/net/phy/mdio_bus.c
|
||||
@@ -303,12 +303,12 @@ void mdiobus_unregister(struct mii_bus *
|
||||
BUG_ON(bus->state != MDIOBUS_REGISTERED);
|
||||
bus->state = MDIOBUS_UNREGISTERED;
|
||||
|
||||
- device_del(&bus->dev);
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++) {
|
||||
if (bus->phy_map[i])
|
||||
device_unregister(&bus->phy_map[i]->dev);
|
||||
bus->phy_map[i] = NULL;
|
||||
}
|
||||
+ device_del(&bus->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(mdiobus_unregister);
|
||||
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Guillaume Nault <g.nault@alphalink.fr>
|
||||
Date: Thu, 24 Sep 2015 12:54:01 +0200
|
||||
Subject: ppp: fix lockdep splat in ppp_dev_uninit()
|
||||
|
||||
From: Guillaume Nault <g.nault@alphalink.fr>
|
||||
|
||||
[ Upstream commit 58a89ecaca53736aa465170530acea4f8be34ab4 ]
|
||||
|
||||
ppp_dev_uninit() locks all_ppp_mutex while under rtnl mutex protection.
|
||||
ppp_create_interface() must then lock these mutexes in that same order
|
||||
to avoid possible deadlock.
|
||||
|
||||
[ 120.880011] ======================================================
|
||||
[ 120.880011] [ INFO: possible circular locking dependency detected ]
|
||||
[ 120.880011] 4.2.0 #1 Not tainted
|
||||
[ 120.880011] -------------------------------------------------------
|
||||
[ 120.880011] ppp-apitest/15827 is trying to acquire lock:
|
||||
[ 120.880011] (&pn->all_ppp_mutex){+.+.+.}, at: [<ffffffffa0145f56>] ppp_dev_uninit+0x64/0xb0 [ppp_generic]
|
||||
[ 120.880011]
|
||||
[ 120.880011] but task is already holding lock:
|
||||
[ 120.880011] (rtnl_mutex){+.+.+.}, at: [<ffffffff812e4255>] rtnl_lock+0x12/0x14
|
||||
[ 120.880011]
|
||||
[ 120.880011] which lock already depends on the new lock.
|
||||
[ 120.880011]
|
||||
[ 120.880011]
|
||||
[ 120.880011] the existing dependency chain (in reverse order) is:
|
||||
[ 120.880011]
|
||||
[ 120.880011] -> #1 (rtnl_mutex){+.+.+.}:
|
||||
[ 120.880011] [<ffffffff81073a6f>] lock_acquire+0xcf/0x10e
|
||||
[ 120.880011] [<ffffffff813ab18a>] mutex_lock_nested+0x56/0x341
|
||||
[ 120.880011] [<ffffffff812e4255>] rtnl_lock+0x12/0x14
|
||||
[ 120.880011] [<ffffffff812d9d94>] register_netdev+0x11/0x27
|
||||
[ 120.880011] [<ffffffffa0147b17>] ppp_ioctl+0x289/0xc98 [ppp_generic]
|
||||
[ 120.880011] [<ffffffff8113b367>] do_vfs_ioctl+0x4ea/0x532
|
||||
[ 120.880011] [<ffffffff8113b3fd>] SyS_ioctl+0x4e/0x7d
|
||||
[ 120.880011] [<ffffffff813ad7d7>] entry_SYSCALL_64_fastpath+0x12/0x6f
|
||||
[ 120.880011]
|
||||
[ 120.880011] -> #0 (&pn->all_ppp_mutex){+.+.+.}:
|
||||
[ 120.880011] [<ffffffff8107334e>] __lock_acquire+0xb07/0xe76
|
||||
[ 120.880011] [<ffffffff81073a6f>] lock_acquire+0xcf/0x10e
|
||||
[ 120.880011] [<ffffffff813ab18a>] mutex_lock_nested+0x56/0x341
|
||||
[ 120.880011] [<ffffffffa0145f56>] ppp_dev_uninit+0x64/0xb0 [ppp_generic]
|
||||
[ 120.880011] [<ffffffff812d5263>] rollback_registered_many+0x19e/0x252
|
||||
[ 120.880011] [<ffffffff812d5381>] rollback_registered+0x29/0x38
|
||||
[ 120.880011] [<ffffffff812d53fa>] unregister_netdevice_queue+0x6a/0x77
|
||||
[ 120.880011] [<ffffffffa0146a94>] ppp_release+0x42/0x79 [ppp_generic]
|
||||
[ 120.880011] [<ffffffff8112d9f6>] __fput+0xec/0x192
|
||||
[ 120.880011] [<ffffffff8112dacc>] ____fput+0x9/0xb
|
||||
[ 120.880011] [<ffffffff8105447a>] task_work_run+0x66/0x80
|
||||
[ 120.880011] [<ffffffff81001801>] prepare_exit_to_usermode+0x8c/0xa7
|
||||
[ 120.880011] [<ffffffff81001900>] syscall_return_slowpath+0xe4/0x104
|
||||
[ 120.880011] [<ffffffff813ad931>] int_ret_from_sys_call+0x25/0x9f
|
||||
[ 120.880011]
|
||||
[ 120.880011] other info that might help us debug this:
|
||||
[ 120.880011]
|
||||
[ 120.880011] Possible unsafe locking scenario:
|
||||
[ 120.880011]
|
||||
[ 120.880011] CPU0 CPU1
|
||||
[ 120.880011] ---- ----
|
||||
[ 120.880011] lock(rtnl_mutex);
|
||||
[ 120.880011] lock(&pn->all_ppp_mutex);
|
||||
[ 120.880011] lock(rtnl_mutex);
|
||||
[ 120.880011] lock(&pn->all_ppp_mutex);
|
||||
[ 120.880011]
|
||||
[ 120.880011] *** DEADLOCK ***
|
||||
|
||||
Fixes: 8cb775bc0a34 ("ppp: fix device unregistration upon netns deletion")
|
||||
Reported-by: Sedat Dilek <sedat.dilek@gmail.com>
|
||||
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
|
||||
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ppp/ppp_generic.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ppp/ppp_generic.c
|
||||
+++ b/drivers/net/ppp/ppp_generic.c
|
||||
@@ -2742,6 +2742,7 @@ static struct ppp *ppp_create_interface(
|
||||
*/
|
||||
dev_net_set(dev, net);
|
||||
|
||||
+ rtnl_lock();
|
||||
mutex_lock(&pn->all_ppp_mutex);
|
||||
|
||||
if (unit < 0) {
|
||||
@@ -2772,7 +2773,7 @@ static struct ppp *ppp_create_interface(
|
||||
ppp->file.index = unit;
|
||||
sprintf(dev->name, "ppp%d", unit);
|
||||
|
||||
- ret = register_netdev(dev);
|
||||
+ ret = register_netdevice(dev);
|
||||
if (ret != 0) {
|
||||
unit_put(&pn->units_idr, unit);
|
||||
netdev_err(ppp->dev, "PPP: couldn't register device %s (%d)\n",
|
||||
@@ -2784,6 +2785,7 @@ static struct ppp *ppp_create_interface(
|
||||
|
||||
atomic_inc(&ppp_unit_count);
|
||||
mutex_unlock(&pn->all_ppp_mutex);
|
||||
+ rtnl_unlock();
|
||||
|
||||
*retp = 0;
|
||||
return ppp;
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
Date: Tue, 15 Sep 2015 14:44:29 -0700
|
||||
Subject: rtnetlink: catch -EOPNOTSUPP errors from ndo_bridge_getlink
|
||||
|
||||
From: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
|
||||
[ Upstream commit d64f69b0373a7d0bcec8b5da7712977518a8f42b ]
|
||||
|
||||
problem reported:
|
||||
kernel 4.1.3
|
||||
------------
|
||||
# bridge vlan
|
||||
port vlan ids
|
||||
eth0 1 PVID Egress Untagged
|
||||
90
|
||||
91
|
||||
92
|
||||
93
|
||||
94
|
||||
95
|
||||
96
|
||||
97
|
||||
98
|
||||
99
|
||||
100
|
||||
|
||||
vmbr0 1 PVID Egress Untagged
|
||||
94
|
||||
|
||||
kernel 4.2
|
||||
-----------
|
||||
# bridge vlan
|
||||
port vlan ids
|
||||
|
||||
ndo_bridge_getlink can return -EOPNOTSUPP when an interfaces
|
||||
ndo_bridge_getlink op is set to switchdev_port_bridge_getlink
|
||||
and CONFIG_SWITCHDEV is not defined. This today can happen to
|
||||
bond, rocker and team devices. This patch adds -EOPNOTSUPP
|
||||
checks after calls to ndo_bridge_getlink.
|
||||
|
||||
Fixes: 85fdb956726ff2a ("switchdev: cut over to new switchdev_port_bridge_getlink")
|
||||
Reported-by: Alexandre DERUMIER <aderumier@odiso.com>
|
||||
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/rtnetlink.c | 26 ++++++++++++++++----------
|
||||
1 file changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -3021,6 +3021,7 @@ static int rtnl_bridge_getlink(struct sk
|
||||
u32 portid = NETLINK_CB(cb->skb).portid;
|
||||
u32 seq = cb->nlh->nlmsg_seq;
|
||||
u32 filter_mask = 0;
|
||||
+ int err;
|
||||
|
||||
if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) {
|
||||
struct nlattr *extfilt;
|
||||
@@ -3041,20 +3042,25 @@ static int rtnl_bridge_getlink(struct sk
|
||||
struct net_device *br_dev = netdev_master_upper_dev_get(dev);
|
||||
|
||||
if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) {
|
||||
- if (idx >= cb->args[0] &&
|
||||
- br_dev->netdev_ops->ndo_bridge_getlink(
|
||||
- skb, portid, seq, dev, filter_mask,
|
||||
- NLM_F_MULTI) < 0)
|
||||
- break;
|
||||
+ if (idx >= cb->args[0]) {
|
||||
+ err = br_dev->netdev_ops->ndo_bridge_getlink(
|
||||
+ skb, portid, seq, dev,
|
||||
+ filter_mask, NLM_F_MULTI);
|
||||
+ if (err < 0 && err != -EOPNOTSUPP)
|
||||
+ break;
|
||||
+ }
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (ops->ndo_bridge_getlink) {
|
||||
- if (idx >= cb->args[0] &&
|
||||
- ops->ndo_bridge_getlink(skb, portid, seq, dev,
|
||||
- filter_mask,
|
||||
- NLM_F_MULTI) < 0)
|
||||
- break;
|
||||
+ if (idx >= cb->args[0]) {
|
||||
+ err = ops->ndo_bridge_getlink(skb, portid,
|
||||
+ seq, dev,
|
||||
+ filter_mask,
|
||||
+ NLM_F_MULTI);
|
||||
+ if (err < 0 && err != -EOPNOTSUPP)
|
||||
+ break;
|
||||
+ }
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
-232
@@ -1,232 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
|
||||
Date: Thu, 10 Sep 2015 17:31:15 -0300
|
||||
Subject: sctp: fix race on protocol/netns initialization
|
||||
|
||||
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
|
||||
|
||||
[ Upstream commit 8e2d61e0aed2b7c4ecb35844fe07e0b2b762dee4 ]
|
||||
|
||||
Consider sctp module is unloaded and is being requested because an user
|
||||
is creating a sctp socket.
|
||||
|
||||
During initialization, sctp will add the new protocol type and then
|
||||
initialize pernet subsys:
|
||||
|
||||
status = sctp_v4_protosw_init();
|
||||
if (status)
|
||||
goto err_protosw_init;
|
||||
|
||||
status = sctp_v6_protosw_init();
|
||||
if (status)
|
||||
goto err_v6_protosw_init;
|
||||
|
||||
status = register_pernet_subsys(&sctp_net_ops);
|
||||
|
||||
The problem is that after those calls to sctp_v{4,6}_protosw_init(), it
|
||||
is possible for userspace to create SCTP sockets like if the module is
|
||||
already fully loaded. If that happens, one of the possible effects is
|
||||
that we will have readers for net->sctp.local_addr_list list earlier
|
||||
than expected and sctp_net_init() does not take precautions while
|
||||
dealing with that list, leading to a potential panic but not limited to
|
||||
that, as sctp_sock_init() will copy a bunch of blank/partially
|
||||
initialized values from net->sctp.
|
||||
|
||||
The race happens like this:
|
||||
|
||||
CPU 0 | CPU 1
|
||||
socket() |
|
||||
__sock_create | socket()
|
||||
inet_create | __sock_create
|
||||
list_for_each_entry_rcu( |
|
||||
answer, &inetsw[sock->type], |
|
||||
list) { | inet_create
|
||||
/* no hits */ |
|
||||
if (unlikely(err)) { |
|
||||
... |
|
||||
request_module() |
|
||||
/* socket creation is blocked |
|
||||
* the module is fully loaded |
|
||||
*/ |
|
||||
sctp_init |
|
||||
sctp_v4_protosw_init |
|
||||
inet_register_protosw |
|
||||
list_add_rcu(&p->list, |
|
||||
last_perm); |
|
||||
| list_for_each_entry_rcu(
|
||||
| answer, &inetsw[sock->type],
|
||||
sctp_v6_protosw_init | list) {
|
||||
| /* hit, so assumes protocol
|
||||
| * is already loaded
|
||||
| */
|
||||
| /* socket creation continues
|
||||
| * before netns is initialized
|
||||
| */
|
||||
register_pernet_subsys |
|
||||
|
||||
Simply inverting the initialization order between
|
||||
register_pernet_subsys() and sctp_v4_protosw_init() is not possible
|
||||
because register_pernet_subsys() will create a control sctp socket, so
|
||||
the protocol must be already visible by then. Deferring the socket
|
||||
creation to a work-queue is not good specially because we loose the
|
||||
ability to handle its errors.
|
||||
|
||||
So, as suggested by Vlad, the fix is to split netns initialization in
|
||||
two moments: defaults and control socket, so that the defaults are
|
||||
already loaded by when we register the protocol, while control socket
|
||||
initialization is kept at the same moment it is today.
|
||||
|
||||
Fixes: 4db67e808640 ("sctp: Make the address lists per network namespace")
|
||||
Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
|
||||
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/sctp/protocol.c | 64 +++++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 41 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/net/sctp/protocol.c
|
||||
+++ b/net/sctp/protocol.c
|
||||
@@ -1166,7 +1166,7 @@ static void sctp_v4_del_protocol(void)
|
||||
unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
|
||||
}
|
||||
|
||||
-static int __net_init sctp_net_init(struct net *net)
|
||||
+static int __net_init sctp_defaults_init(struct net *net)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -1259,12 +1259,6 @@ static int __net_init sctp_net_init(stru
|
||||
|
||||
sctp_dbg_objcnt_init(net);
|
||||
|
||||
- /* Initialize the control inode/socket for handling OOTB packets. */
|
||||
- if ((status = sctp_ctl_sock_init(net))) {
|
||||
- pr_err("Failed to initialize the SCTP control sock\n");
|
||||
- goto err_ctl_sock_init;
|
||||
- }
|
||||
-
|
||||
/* Initialize the local address list. */
|
||||
INIT_LIST_HEAD(&net->sctp.local_addr_list);
|
||||
spin_lock_init(&net->sctp.local_addr_lock);
|
||||
@@ -1280,9 +1274,6 @@ static int __net_init sctp_net_init(stru
|
||||
|
||||
return 0;
|
||||
|
||||
-err_ctl_sock_init:
|
||||
- sctp_dbg_objcnt_exit(net);
|
||||
- sctp_proc_exit(net);
|
||||
err_init_proc:
|
||||
cleanup_sctp_mibs(net);
|
||||
err_init_mibs:
|
||||
@@ -1291,15 +1282,12 @@ err_sysctl_register:
|
||||
return status;
|
||||
}
|
||||
|
||||
-static void __net_exit sctp_net_exit(struct net *net)
|
||||
+static void __net_exit sctp_defaults_exit(struct net *net)
|
||||
{
|
||||
/* Free the local address list */
|
||||
sctp_free_addr_wq(net);
|
||||
sctp_free_local_addr_list(net);
|
||||
|
||||
- /* Free the control endpoint. */
|
||||
- inet_ctl_sock_destroy(net->sctp.ctl_sock);
|
||||
-
|
||||
sctp_dbg_objcnt_exit(net);
|
||||
|
||||
sctp_proc_exit(net);
|
||||
@@ -1307,9 +1295,32 @@ static void __net_exit sctp_net_exit(str
|
||||
sctp_sysctl_net_unregister(net);
|
||||
}
|
||||
|
||||
-static struct pernet_operations sctp_net_ops = {
|
||||
- .init = sctp_net_init,
|
||||
- .exit = sctp_net_exit,
|
||||
+static struct pernet_operations sctp_defaults_ops = {
|
||||
+ .init = sctp_defaults_init,
|
||||
+ .exit = sctp_defaults_exit,
|
||||
+};
|
||||
+
|
||||
+static int __net_init sctp_ctrlsock_init(struct net *net)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ /* Initialize the control inode/socket for handling OOTB packets. */
|
||||
+ status = sctp_ctl_sock_init(net);
|
||||
+ if (status)
|
||||
+ pr_err("Failed to initialize the SCTP control sock\n");
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static void __net_init sctp_ctrlsock_exit(struct net *net)
|
||||
+{
|
||||
+ /* Free the control endpoint. */
|
||||
+ inet_ctl_sock_destroy(net->sctp.ctl_sock);
|
||||
+}
|
||||
+
|
||||
+static struct pernet_operations sctp_ctrlsock_ops = {
|
||||
+ .init = sctp_ctrlsock_init,
|
||||
+ .exit = sctp_ctrlsock_exit,
|
||||
};
|
||||
|
||||
/* Initialize the universe into something sensible. */
|
||||
@@ -1442,8 +1453,11 @@ static __init int sctp_init(void)
|
||||
sctp_v4_pf_init();
|
||||
sctp_v6_pf_init();
|
||||
|
||||
- status = sctp_v4_protosw_init();
|
||||
+ status = register_pernet_subsys(&sctp_defaults_ops);
|
||||
+ if (status)
|
||||
+ goto err_register_defaults;
|
||||
|
||||
+ status = sctp_v4_protosw_init();
|
||||
if (status)
|
||||
goto err_protosw_init;
|
||||
|
||||
@@ -1451,9 +1465,9 @@ static __init int sctp_init(void)
|
||||
if (status)
|
||||
goto err_v6_protosw_init;
|
||||
|
||||
- status = register_pernet_subsys(&sctp_net_ops);
|
||||
+ status = register_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
if (status)
|
||||
- goto err_register_pernet_subsys;
|
||||
+ goto err_register_ctrlsock;
|
||||
|
||||
status = sctp_v4_add_protocol();
|
||||
if (status)
|
||||
@@ -1469,12 +1483,14 @@ out:
|
||||
err_v6_add_protocol:
|
||||
sctp_v4_del_protocol();
|
||||
err_add_protocol:
|
||||
- unregister_pernet_subsys(&sctp_net_ops);
|
||||
-err_register_pernet_subsys:
|
||||
+ unregister_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
+err_register_ctrlsock:
|
||||
sctp_v6_protosw_exit();
|
||||
err_v6_protosw_init:
|
||||
sctp_v4_protosw_exit();
|
||||
err_protosw_init:
|
||||
+ unregister_pernet_subsys(&sctp_defaults_ops);
|
||||
+err_register_defaults:
|
||||
sctp_v4_pf_exit();
|
||||
sctp_v6_pf_exit();
|
||||
sctp_sysctl_unregister();
|
||||
@@ -1507,12 +1523,14 @@ static __exit void sctp_exit(void)
|
||||
sctp_v6_del_protocol();
|
||||
sctp_v4_del_protocol();
|
||||
|
||||
- unregister_pernet_subsys(&sctp_net_ops);
|
||||
+ unregister_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
|
||||
/* Free protosw registrations */
|
||||
sctp_v6_protosw_exit();
|
||||
sctp_v4_protosw_exit();
|
||||
|
||||
+ unregister_pernet_subsys(&sctp_defaults_ops);
|
||||
+
|
||||
/* Unregister with socket layer. */
|
||||
sctp_v6_pf_exit();
|
||||
sctp_v4_pf_exit();
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Date: Wed, 2 Sep 2015 14:00:36 +0200
|
||||
Subject: sock, diag: fix panic in sock_diag_put_filterinfo
|
||||
|
||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
||||
|
||||
[ Upstream commit b382c08656000c12a146723a153b85b13a855b49 ]
|
||||
|
||||
diag socket's sock_diag_put_filterinfo() dumps classic BPF programs
|
||||
upon request to user space (ss -0 -b). However, native eBPF programs
|
||||
attached to sockets (SO_ATTACH_BPF) cannot be dumped with this method:
|
||||
|
||||
Their orig_prog is always NULL. However, sock_diag_put_filterinfo()
|
||||
unconditionally tries to access its filter length resp. wants to copy
|
||||
the filter insns from there. Internal cBPF to eBPF transformations
|
||||
attached to sockets don't have this issue, as orig_prog state is kept.
|
||||
|
||||
It's currently only used by packet sockets. If we would want to add
|
||||
native eBPF support in the future, this needs to be done through
|
||||
a different attribute than PACKET_DIAG_FILTER to not confuse possible
|
||||
user space disassemblers that work on diag data.
|
||||
|
||||
Fixes: 89aa075832b0 ("net: sock: allow eBPF programs to be attached to sockets")
|
||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
||||
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
|
||||
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/sock_diag.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/net/core/sock_diag.c
|
||||
+++ b/net/core/sock_diag.c
|
||||
@@ -90,6 +90,9 @@ int sock_diag_put_filterinfo(bool may_re
|
||||
goto out;
|
||||
|
||||
fprog = filter->prog->orig_prog;
|
||||
+ if (!fprog)
|
||||
+ goto out;
|
||||
+
|
||||
flen = bpf_classic_proglen(fprog);
|
||||
|
||||
attr = nla_reserve(skb, attrtype, flen);
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
From foo@baz Wed Sep 30 05:25:07 CEST 2015
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Wed, 23 Sep 2015 14:00:21 -0700
|
||||
Subject: tcp: add proper TS val into RST packets
|
||||
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
|
||||
[ Upstream commit 675ee231d960af2af3606b4480324e26797eb010 ]
|
||||
|
||||
RST packets sent on behalf of TCP connections with TS option (RFC 7323
|
||||
TCP timestamps) have incorrect TS val (set to 0), but correct TS ecr.
|
||||
|
||||
A > B: Flags [S], seq 0, win 65535, options [mss 1000,nop,nop,TS val 100
|
||||
ecr 0], length 0
|
||||
B > A: Flags [S.], seq 2444755794, ack 1, win 28960, options [mss
|
||||
1460,nop,nop,TS val 7264344 ecr 100], length 0
|
||||
A > B: Flags [.], ack 1, win 65535, options [nop,nop,TS val 110 ecr
|
||||
7264344], length 0
|
||||
|
||||
B > A: Flags [R.], seq 1, ack 1, win 28960, options [nop,nop,TS val 0
|
||||
ecr 110], length 0
|
||||
|
||||
We need to call skb_mstamp_get() to get proper TS val,
|
||||
derived from skb->skb_mstamp
|
||||
|
||||
Note that RFC 1323 was advocating to not send TS option in RST segment,
|
||||
but RFC 7323 recommends the opposite :
|
||||
|
||||
Once TSopt has been successfully negotiated, that is both <SYN> and
|
||||
<SYN,ACK> contain TSopt, the TSopt MUST be sent in every non-<RST>
|
||||
segment for the duration of the connection, and SHOULD be sent in an
|
||||
<RST> segment (see Section 5.2 for details)
|
||||
|
||||
Note this RFC recommends to send TS val = 0, but we believe it is
|
||||
premature : We do not know if all TCP stacks are properly
|
||||
handling the receive side :
|
||||
|
||||
When an <RST> segment is
|
||||
received, it MUST NOT be subjected to the PAWS check by verifying an
|
||||
acceptable value in SEG.TSval, and information from the Timestamps
|
||||
option MUST NOT be used to update connection state information.
|
||||
SEG.TSecr MAY be used to provide stricter <RST> acceptance checks.
|
||||
|
||||
In 5 years, if/when all TCP stack are RFC 7323 ready, we might consider
|
||||
to decide to send TS val = 0, if it buys something.
|
||||
|
||||
Fixes: 7faee5c0d514 ("tcp: remove TCP_SKB_CB(skb)->when")
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Acked-by: Yuchung Cheng <ycheng@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv4/tcp_output.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/net/ipv4/tcp_output.c
|
||||
+++ b/net/ipv4/tcp_output.c
|
||||
@@ -2898,6 +2898,7 @@ void tcp_send_active_reset(struct sock *
|
||||
skb_reserve(skb, MAX_TCP_HEADER);
|
||||
tcp_init_nondata_skb(skb, tcp_acceptable_seq(sk),
|
||||
TCPHDR_ACK | TCPHDR_RST);
|
||||
+ skb_mstamp_get(&skb->skb_mstamp);
|
||||
/* Send it off. */
|
||||
if (tcp_transmit_skb(sk, skb, 0, priority))
|
||||
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTFAILED);
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
From a42fb351ca1f340f8307468be765e3f77ddedda9 Mon Sep 17 00:00:00 2001
|
||||
From: Knuth Posern <knuth@posern.org>
|
||||
Date: Sun, 20 Sep 2015 21:25:22 +0200
|
||||
Subject: [PATCH] thunderbolt: Allow loading of module on recent Apple MacBooks
|
||||
with thunderbolt 2 controller
|
||||
|
||||
The pci device ids listed in the thunderbolt driver are to restrictive,
|
||||
which prevents the driver from being loaded on recent Apple MacBooks
|
||||
using a thunderbolt 2 controller. In particular this prevented any
|
||||
hot-plugging functionality for thunderbolt based ethernet dongles
|
||||
(i.e. Apples thunderbolt gigabit ethernet broadcom tg3 based dongle
|
||||
Model A1433 EMC 2590).
|
||||
|
||||
Changing the subvendor and subdevice to PCI_ANY_ID the thunderbolt driver
|
||||
loads and binds to the pci device 07:00.0 System peripheral:
|
||||
Intel Corporation Device 156c which is the thunderbolt 2 controller on
|
||||
the MacBookPro12,1.
|
||||
|
||||
Successfully tested on MacBookPro12,1. With the patch the thunderbolt
|
||||
module gets now loaded on boot. And it provides hot-plugging support both
|
||||
for a cold-plugged and a warm-plugged ethernet dongle.
|
||||
|
||||
Signed-off-by: Andreas Noever <andreas.noever@gmail.com>
|
||||
Acked-by: Knuth Posern <knuth@posern.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/thunderbolt/nhi.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
|
||||
index c68fe12..20a41f7 100644
|
||||
--- a/drivers/thunderbolt/nhi.c
|
||||
+++ b/drivers/thunderbolt/nhi.c
|
||||
@@ -643,7 +643,7 @@ static struct pci_device_id nhi_ids[] = {
|
||||
{
|
||||
.class = PCI_CLASS_SYSTEM_OTHER << 8, .class_mask = ~0,
|
||||
.vendor = PCI_VENDOR_ID_INTEL, .device = 0x156c,
|
||||
- .subvendor = 0x2222, .subdevice = 0x1111,
|
||||
+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
|
||||
},
|
||||
{ 0,}
|
||||
};
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 762982db33b23029e98c844611e2e8beeb75bc0d Mon Sep 17 00:00:00 2001
|
||||
From: Roger Quadros <rogerq@ti.com>
|
||||
Date: Thu, 13 Aug 2015 13:28:42 +0300
|
||||
Subject: [PATCH] usb: phy: phy-generic: Fix reset behaviour on legacy boot
|
||||
|
||||
The gpio-desc migration done in v4.0 caused a regression
|
||||
with legacy boots due to reversed reset logic.
|
||||
e.g. omap3-beagle USB host breaks on legacy boot.
|
||||
|
||||
Request the reset GPIO with GPIOF_ACTIVE_LOW flag so that
|
||||
it matches the driver logic and pin behaviour.
|
||||
|
||||
Fixes: e9f2cefb0cdc ("usb: phy: generic: migrate to gpio_desc")
|
||||
Cc: <stable@vger.kernel.org> # 4.0+
|
||||
Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Signed-off-by: Roger Quadros <rogerq@ti.com>
|
||||
Signed-off-by: Felipe Balbi <balbi@ti.com>
|
||||
---
|
||||
drivers/usb/phy/phy-generic.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
|
||||
index ec6ecd0..5320cb8 100644
|
||||
--- a/drivers/usb/phy/phy-generic.c
|
||||
+++ b/drivers/usb/phy/phy-generic.c
|
||||
@@ -232,7 +232,8 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop,
|
||||
clk_rate = pdata->clk_rate;
|
||||
needs_vcc = pdata->needs_vcc;
|
||||
if (gpio_is_valid(pdata->gpio_reset)) {
|
||||
- err = devm_gpio_request_one(dev, pdata->gpio_reset, 0,
|
||||
+ err = devm_gpio_request_one(dev, pdata->gpio_reset,
|
||||
+ GPIOF_ACTIVE_LOW,
|
||||
dev_name(dev));
|
||||
if (!err)
|
||||
nop->gpiod_reset =
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From dca7794539eff04b786fb6907186989e5eaaa9c2 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Date: Mon, 21 Sep 2015 17:46:16 +0300
|
||||
Subject: [PATCH] xhci: change xhci 1.0 only restrictions to support xhci 1.1
|
||||
|
||||
Some changes between xhci 0.96 and xhci 1.0 specifications forced us to
|
||||
check the hci version in code, some of these checks were implemented as
|
||||
hci_version == 1.0, which will not work with new xhci 1.1 controllers.
|
||||
|
||||
xhci 1.1 behaves similar to xhci 1.0 in these cases, so change these
|
||||
checks to hci_version >= 1.0
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/xhci-mem.c | 6 +++---
|
||||
drivers/usb/host/xhci-ring.c | 4 ++--
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
|
||||
index 9a8c936..8497fb8 100644
|
||||
--- a/drivers/usb/host/xhci-mem.c
|
||||
+++ b/drivers/usb/host/xhci-mem.c
|
||||
@@ -1498,10 +1498,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||
* use Event Data TRBs, and we don't chain in a link TRB on short
|
||||
* transfers, we're basically dividing by 1.
|
||||
*
|
||||
- * xHCI 1.0 specification indicates that the Average TRB Length should
|
||||
- * be set to 8 for control endpoints.
|
||||
+ * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length
|
||||
+ * should be set to 8 for control endpoints.
|
||||
*/
|
||||
- if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version == 0x100)
|
||||
+ if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
|
||||
ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8));
|
||||
else
|
||||
ep_ctx->tx_info |=
|
||||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
||||
index 1c61e5e..43291f9 100644
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -3470,8 +3470,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
||||
if (start_cycle == 0)
|
||||
field |= 0x1;
|
||||
|
||||
- /* xHCI 1.0 6.4.1.2.1: Transfer Type field */
|
||||
- if (xhci->hci_version == 0x100) {
|
||||
+ /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
|
||||
+ if (xhci->hci_version >= 0x100) {
|
||||
if (urb->transfer_buffer_length > 0) {
|
||||
if (setup->bRequestType & USB_DIR_IN)
|
||||
field |= TRB_TX_TYPE(TRB_DATA_IN);
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
From a5caa209ba9c29c6421292e7879d2387a2ef39c9 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Fleming <matt.fleming@intel.com>
|
||||
Date: Fri, 25 Sep 2015 23:02:18 +0100
|
||||
Subject: [PATCH] x86/efi: Fix boot crash by mapping EFI memmap entries
|
||||
bottom-up at runtime, instead of top-down
|
||||
|
||||
Beginning with UEFI v2.5 EFI_PROPERTIES_TABLE was introduced
|
||||
that signals that the firmware PE/COFF loader supports splitting
|
||||
code and data sections of PE/COFF images into separate EFI
|
||||
memory map entries. This allows the kernel to map those regions
|
||||
with strict memory protections, e.g. EFI_MEMORY_RO for code,
|
||||
EFI_MEMORY_XP for data, etc.
|
||||
|
||||
Unfortunately, an unwritten requirement of this new feature is
|
||||
that the regions need to be mapped with the same offsets
|
||||
relative to each other as observed in the EFI memory map. If
|
||||
this is not done crashes like this may occur,
|
||||
|
||||
BUG: unable to handle kernel paging request at fffffffefe6086dd
|
||||
IP: [<fffffffefe6086dd>] 0xfffffffefe6086dd
|
||||
Call Trace:
|
||||
[<ffffffff8104c90e>] efi_call+0x7e/0x100
|
||||
[<ffffffff81602091>] ? virt_efi_set_variable+0x61/0x90
|
||||
[<ffffffff8104c583>] efi_delete_dummy_variable+0x63/0x70
|
||||
[<ffffffff81f4e4aa>] efi_enter_virtual_mode+0x383/0x392
|
||||
[<ffffffff81f37e1b>] start_kernel+0x38a/0x417
|
||||
[<ffffffff81f37495>] x86_64_start_reservations+0x2a/0x2c
|
||||
[<ffffffff81f37582>] x86_64_start_kernel+0xeb/0xef
|
||||
|
||||
Here 0xfffffffefe6086dd refers to an address the firmware
|
||||
expects to be mapped but which the OS never claimed was mapped.
|
||||
The issue is that included in these regions are relative
|
||||
addresses to other regions which were emitted by the firmware
|
||||
toolchain before the "splitting" of sections occurred at
|
||||
runtime.
|
||||
|
||||
Needless to say, we don't satisfy this unwritten requirement on
|
||||
x86_64 and instead map the EFI memory map entries in reverse
|
||||
order. The above crash is almost certainly triggerable with any
|
||||
kernel newer than v3.13 because that's when we rewrote the EFI
|
||||
runtime region mapping code, in commit d2f7cbe7b26a ("x86/efi:
|
||||
Runtime services virtual mapping"). For kernel versions before
|
||||
v3.13 things may work by pure luck depending on the
|
||||
fragmentation of the kernel virtual address space at the time we
|
||||
map the EFI regions.
|
||||
|
||||
Instead of mapping the EFI memory map entries in reverse order,
|
||||
where entry N has a higher virtual address than entry N+1, map
|
||||
them in the same order as they appear in the EFI memory map to
|
||||
preserve this relative offset between regions.
|
||||
|
||||
This patch has been kept as small as possible with the intention
|
||||
that it should be applied aggressively to stable and
|
||||
distribution kernels. It is very much a bugfix rather than
|
||||
support for a new feature, since when EFI_PROPERTIES_TABLE is
|
||||
enabled we must map things as outlined above to even boot - we
|
||||
have no way of asking the firmware not to split the code/data
|
||||
regions.
|
||||
|
||||
In fact, this patch doesn't even make use of the more strict
|
||||
memory protections available in UEFI v2.5. That will come later.
|
||||
|
||||
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Cc: Borislav Petkov <bp@suse.de>
|
||||
Cc: Chun-Yi <jlee@suse.com>
|
||||
Cc: Dave Young <dyoung@redhat.com>
|
||||
Cc: H. Peter Anvin <hpa@zytor.com>
|
||||
Cc: James Bottomley <JBottomley@Odin.com>
|
||||
Cc: Lee, Chun-Yi <jlee@suse.com>
|
||||
Cc: Leif Lindholm <leif.lindholm@linaro.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Cc: Mike Galbraith <efault@gmx.de>
|
||||
Cc: Peter Jones <pjones@redhat.com>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
Link: http://lkml.kernel.org/r/1443218539-7610-2-git-send-email-matt@codeblueprint.co.uk
|
||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
||||
---
|
||||
arch/x86/platform/efi/efi.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 66 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
|
||||
index 1db84c0..6a28ded 100644
|
||||
--- a/arch/x86/platform/efi/efi.c
|
||||
+++ b/arch/x86/platform/efi/efi.c
|
||||
@@ -705,6 +705,70 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Iterate the EFI memory map in reverse order because the regions
|
||||
+ * will be mapped top-down. The end result is the same as if we had
|
||||
+ * mapped things forward, but doesn't require us to change the
|
||||
+ * existing implementation of efi_map_region().
|
||||
+ */
|
||||
+static inline void *efi_map_next_entry_reverse(void *entry)
|
||||
+{
|
||||
+ /* Initial call */
|
||||
+ if (!entry)
|
||||
+ return memmap.map_end - memmap.desc_size;
|
||||
+
|
||||
+ entry -= memmap.desc_size;
|
||||
+ if (entry < memmap.map)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return entry;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * efi_map_next_entry - Return the next EFI memory map descriptor
|
||||
+ * @entry: Previous EFI memory map descriptor
|
||||
+ *
|
||||
+ * This is a helper function to iterate over the EFI memory map, which
|
||||
+ * we do in different orders depending on the current configuration.
|
||||
+ *
|
||||
+ * To begin traversing the memory map @entry must be %NULL.
|
||||
+ *
|
||||
+ * Returns %NULL when we reach the end of the memory map.
|
||||
+ */
|
||||
+static void *efi_map_next_entry(void *entry)
|
||||
+{
|
||||
+ if (!efi_enabled(EFI_OLD_MEMMAP) && efi_enabled(EFI_64BIT)) {
|
||||
+ /*
|
||||
+ * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE
|
||||
+ * config table feature requires us to map all entries
|
||||
+ * in the same order as they appear in the EFI memory
|
||||
+ * map. That is to say, entry N must have a lower
|
||||
+ * virtual address than entry N+1. This is because the
|
||||
+ * firmware toolchain leaves relative references in
|
||||
+ * the code/data sections, which are split and become
|
||||
+ * separate EFI memory regions. Mapping things
|
||||
+ * out-of-order leads to the firmware accessing
|
||||
+ * unmapped addresses.
|
||||
+ *
|
||||
+ * Since we need to map things this way whether or not
|
||||
+ * the kernel actually makes use of
|
||||
+ * EFI_PROPERTIES_TABLE, let's just switch to this
|
||||
+ * scheme by default for 64-bit.
|
||||
+ */
|
||||
+ return efi_map_next_entry_reverse(entry);
|
||||
+ }
|
||||
+
|
||||
+ /* Initial call */
|
||||
+ if (!entry)
|
||||
+ return memmap.map;
|
||||
+
|
||||
+ entry += memmap.desc_size;
|
||||
+ if (entry >= memmap.map_end)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return entry;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Map the efi memory ranges of the runtime services and update new_mmap with
|
||||
* virtual addresses.
|
||||
*/
|
||||
@@ -714,7 +778,8 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
|
||||
unsigned long left = 0;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
- for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
||||
+ p = NULL;
|
||||
+ while ((p = efi_map_next_entry(p))) {
|
||||
md = p;
|
||||
if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
|
||||
#ifdef CONFIG_X86_64
|
||||
--
|
||||
2.6.0
|
||||
|
||||
+23
-3
@@ -12,7 +12,6 @@
|
||||
<IsA>kernel</IsA>
|
||||
<Summary>The Linux kernel (the core of the Linux operating system) for Pisi Linux</Summary>
|
||||
<Description>kernel contains the Linux kernel, the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc.</Description>
|
||||
<!--Archive sha1sum="dce24ac1874f362000e40027075e7d24ba123b73" type="targz">https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.1.tar.gz</Archive-->
|
||||
<Archive sha1sum="70db3c22960e3da16b7d7b0a55066154b8d92900" type="targz">https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.2.tar.gz</Archive>
|
||||
<AdditionalFiles>
|
||||
<AdditionalFile target="configs/kernel-i686-config">configs/kernel-i686-config</AdditionalFile>
|
||||
@@ -29,13 +28,14 @@
|
||||
</BuildDependencies>
|
||||
<Patches>
|
||||
<!-- Linux patches -->
|
||||
<Patch level="1" compressionType="xz">patches/linux/patch-4.2.2.xz</Patch>
|
||||
<!-- Mageia Linux patches // compatible with http://svnweb.mageia.org/packages/cauldron/kernel/releases/4.2.2/1.mga6/PATCHES/patches/series-->
|
||||
<Patch level="1" compressionType="xz">patches/linux/patch-4.2.3.xz</Patch>
|
||||
<!-- Mageia Linux patches // compatible with http://svnweb.mageia.org/packages/cauldron/kernel/releases/4.2.3/1.mga6/PATCHES/patches/series-->
|
||||
<Patch level="1">patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch</Patch>
|
||||
<Patch level="1">patches/mageia/x86-boot-video-80x25-if-break.patch</Patch>
|
||||
<Patch level="1">patches/mageia/x86-default_poweroff_up_machines.patch</Patch>
|
||||
<Patch level="1">patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch</Patch>
|
||||
<Patch level="1">patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch</Patch>
|
||||
<Patch level="1">patches/mageia/x86-efi-Fix-boot-crash-by-mapping-EFI-memmap-entries.patch</Patch>
|
||||
<Patch level="1">patches/mageia/cpu-cacheinfo-Fix-teardown-path.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pci-quirks-drop-devinit-exit.patch</Patch>
|
||||
@@ -56,6 +56,8 @@
|
||||
<Patch level="1">patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-aufs4.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-aufs4-modular.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-dcache-Handle-escaped-paths-in-prepend_path.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-vfs-Test-for-and-handle-paths-that-are-unreachable-from-their-mnt_root.patch</Patch>
|
||||
<Patch level="1">patches/mageia/firewire-ieee1394-module-aliases.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-agp-intel-new-Q57-id.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-mach64.patch</Patch>
|
||||
@@ -86,13 +88,23 @@
|
||||
<Patch level="1">patches/mageia/net-netfilter-psd.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-psd-mdv.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-conntrack-use-nf_ct_tmpl_free-in-CT-synpro.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-nfnetlink-work-around-wrong-endianess-in-r.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-bridge-fix-IPv6-packets-not-being-bridged-.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-nf_tables-Use-32-bit-addressing-register-f.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-ipset-Out-of-bound-access-in-hash-net-type.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-ipset-Fixing-unnamed-union-init.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-wireless-rtlwifi-rtl8821ae-Fix-system-lockups-on-boot.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-add-shuttle-wmi-driver.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/include-kbuild-export-pci_ids.patch</Patch>
|
||||
<Patch level="1">patches/mageia/thunderbolt-Allow-loading-of-module-on-recent-Apple-.patch</Patch>
|
||||
<Patch level="1">patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-storage-unusual_devs-add-id.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-phy-phy-generic-Fix-reset-behaviour-on-legacy-bo.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-xhci-change-xhci-1.0-only-restrictions-to-support-xh.patch</Patch>
|
||||
<Patch level="1">patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-3rdparty-1.0-tree.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-3rdparty-merge.patch</Patch>
|
||||
@@ -180,6 +192,14 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="63">
|
||||
<Date>2015-10-04</Date>
|
||||
<Version>4.2.3</Version>
|
||||
<Comment>Version bump to 4.2.3 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.2.3</Comment>
|
||||
<Type package="kernel">security</Type>
|
||||
<Name>Ertuğrul Erata</Name>
|
||||
<Email>ertugrulerata@gmail.com</Email>
|
||||
</Update>
|
||||
<Update release="62">
|
||||
<Date>2015-10-01</Date>
|
||||
<Version>4.2.2</Version>
|
||||
|
||||
Reference in New Issue
Block a user