]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Jan 2016 06:29:58 +0000 (22:29 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Jan 2016 06:29:58 +0000 (22:29 -0800)
added patches:
batman-adv-avoid-recursive-call_rcu-for-batadv_bla_claim.patch
batman-adv-avoid-recursive-call_rcu-for-batadv_nc_node.patch
batman-adv-drop-immediate-batadv_hard_iface-free-function.patch
batman-adv-drop-immediate-batadv_neigh_node-free-function.patch
batman-adv-drop-immediate-batadv_orig_ifinfo-free-function.patch
batman-adv-drop-immediate-neigh_ifinfo-free-function.patch
batman-adv-drop-immediate-orig_node-free-function.patch
bonding-prevent-ipv6-link-local-address-on-enslaved-devices.patch
bridge-fix-lockdep-addr_list_lock-false-positive-splat.patch
dwc_eth_qos-fix-dma-address-for-multi-fragment-skbs.patch
ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch
ipv6-update-skb-csum-when-ce-mark-is-propagated.patch
net-bpf-reject-invalid-shifts.patch
net-mlx5_core-fix-trimming-down-irq-number.patch
net-pktgen-fix-null-ptr-deref-in-skb-allocation.patch
net-preserve-ip-control-block-during-gso-segmentation.patch
net-sctp-prevent-writes-to-cookie_hmac_alg-from-accessing-invalid-memory.patch
phonet-properly-unshare-skbs-in-phonet_rcv.patch
sched-cls_flower-set-key-address-type-when-present.patch
tcp_yeah-don-t-set-ssthresh-below-2.patch
team-replace-rcu_read_lock-with-a-mutex-in-team_vlan_rx_kill_vid.patch
udp-disallow-ufo-for-sockets-with-so_no_check-option.patch
unix-properly-account-for-fds-passed-over-unix-sockets.patch
vxlan-fix-test-which-detect-duplicate-vxlan-iface.patch

25 files changed:
queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_bla_claim.patch [new file with mode: 0644]
queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_nc_node.patch [new file with mode: 0644]
queue-4.4/batman-adv-drop-immediate-batadv_hard_iface-free-function.patch [new file with mode: 0644]
queue-4.4/batman-adv-drop-immediate-batadv_neigh_node-free-function.patch [new file with mode: 0644]
queue-4.4/batman-adv-drop-immediate-batadv_orig_ifinfo-free-function.patch [new file with mode: 0644]
queue-4.4/batman-adv-drop-immediate-neigh_ifinfo-free-function.patch [new file with mode: 0644]
queue-4.4/batman-adv-drop-immediate-orig_node-free-function.patch [new file with mode: 0644]
queue-4.4/bonding-prevent-ipv6-link-local-address-on-enslaved-devices.patch [new file with mode: 0644]
queue-4.4/bridge-fix-lockdep-addr_list_lock-false-positive-splat.patch [new file with mode: 0644]
queue-4.4/dwc_eth_qos-fix-dma-address-for-multi-fragment-skbs.patch [new file with mode: 0644]
queue-4.4/ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch [new file with mode: 0644]
queue-4.4/ipv6-update-skb-csum-when-ce-mark-is-propagated.patch [new file with mode: 0644]
queue-4.4/net-bpf-reject-invalid-shifts.patch [new file with mode: 0644]
queue-4.4/net-mlx5_core-fix-trimming-down-irq-number.patch [new file with mode: 0644]
queue-4.4/net-pktgen-fix-null-ptr-deref-in-skb-allocation.patch [new file with mode: 0644]
queue-4.4/net-preserve-ip-control-block-during-gso-segmentation.patch [new file with mode: 0644]
queue-4.4/net-sctp-prevent-writes-to-cookie_hmac_alg-from-accessing-invalid-memory.patch [new file with mode: 0644]
queue-4.4/phonet-properly-unshare-skbs-in-phonet_rcv.patch [new file with mode: 0644]
queue-4.4/sched-cls_flower-set-key-address-type-when-present.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/tcp_yeah-don-t-set-ssthresh-below-2.patch [new file with mode: 0644]
queue-4.4/team-replace-rcu_read_lock-with-a-mutex-in-team_vlan_rx_kill_vid.patch [new file with mode: 0644]
queue-4.4/udp-disallow-ufo-for-sockets-with-so_no_check-option.patch [new file with mode: 0644]
queue-4.4/unix-properly-account-for-fds-passed-over-unix-sockets.patch [new file with mode: 0644]
queue-4.4/vxlan-fix-test-which-detect-duplicate-vxlan-iface.patch [new file with mode: 0644]

diff --git a/queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_bla_claim.patch b/queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_bla_claim.patch
new file mode 100644 (file)
index 0000000..b2a9848
--- /dev/null
@@ -0,0 +1,61 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 14 Jan 2016 15:28:19 +0100
+Subject: batman-adv: Avoid recursive call_rcu for batadv_bla_claim
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit 63b399272294e7a939cde41792dca38c549f0484 ]
+
+The batadv_claim_free_ref function uses call_rcu to delay the free of the
+batadv_bla_claim object until no (already started) rcu_read_lock is enabled
+anymore. This makes sure that no context is still trying to access the
+object which should be removed. But batadv_bla_claim also contains a
+reference to backbone_gw which must be removed.
+
+The reference drop of backbone_gw was done in the call_rcu function
+batadv_claim_free_rcu but should actually be done in the
+batadv_claim_release function to avoid nested call_rcus. This is important
+because rcu_barrier (e.g. batadv_softif_free or batadv_exit) will not
+detect the inner call_rcu as relevant for its execution. Otherwise this
+barrier will most likely be inserted in the queue before the callback of
+the first call_rcu was executed. The caller of rcu_barrier will therefore
+continue to run before the inner call_rcu callback finished.
+
+Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bridge_loop_avoidance.c |   10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -127,21 +127,17 @@ batadv_backbone_gw_free_ref(struct batad
+ }
+ /* finally deinitialize the claim */
+-static void batadv_claim_free_rcu(struct rcu_head *rcu)
++static void batadv_claim_release(struct batadv_bla_claim *claim)
+ {
+-      struct batadv_bla_claim *claim;
+-
+-      claim = container_of(rcu, struct batadv_bla_claim, rcu);
+-
+       batadv_backbone_gw_free_ref(claim->backbone_gw);
+-      kfree(claim);
++      kfree_rcu(claim, rcu);
+ }
+ /* free a claim, call claim_free_rcu if its the last reference */
+ static void batadv_claim_free_ref(struct batadv_bla_claim *claim)
+ {
+       if (atomic_dec_and_test(&claim->refcount))
+-              call_rcu(&claim->rcu, batadv_claim_free_rcu);
++              batadv_claim_release(claim);
+ }
+ /**
diff --git a/queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_nc_node.patch b/queue-4.4/batman-adv-avoid-recursive-call_rcu-for-batadv_nc_node.patch
new file mode 100644 (file)
index 0000000..a91a5ce
--- /dev/null
@@ -0,0 +1,72 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:19 +0100
+Subject: batman-adv: Avoid recursive call_rcu for batadv_nc_node
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit 44e8e7e91d6c7c7ab19688750f7257292640d1a0 ]
+
+The batadv_nc_node_free_ref function uses call_rcu to delay the free of the
+batadv_nc_node object until no (already started) rcu_read_lock is enabled
+anymore. This makes sure that no context is still trying to access the
+object which should be removed. But batadv_nc_node also contains a
+reference to orig_node which must be removed.
+
+The reference drop of orig_node was done in the call_rcu function
+batadv_nc_node_free_rcu but should actually be done in the
+batadv_nc_node_release function to avoid nested call_rcus. This is
+important because rcu_barrier (e.g. batadv_softif_free or batadv_exit) will
+not detect the inner call_rcu as relevant for its execution. Otherwise this
+barrier will most likely be inserted in the queue before the callback of
+the first call_rcu was executed. The caller of rcu_barrier will therefore
+continue to run before the inner call_rcu callback finished.
+
+Fixes: d56b1705e28c ("batman-adv: network coding - detect coding nodes and remove these after timeout")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/network-coding.c |   19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+--- a/net/batman-adv/network-coding.c
++++ b/net/batman-adv/network-coding.c
+@@ -203,28 +203,25 @@ void batadv_nc_init_orig(struct batadv_o
+ }
+ /**
+- * batadv_nc_node_free_rcu - rcu callback to free an nc node and remove
+- *  its refcount on the orig_node
+- * @rcu: rcu pointer of the nc node
++ * batadv_nc_node_release - release nc_node from lists and queue for free after
++ *  rcu grace period
++ * @nc_node: the nc node to free
+  */
+-static void batadv_nc_node_free_rcu(struct rcu_head *rcu)
++static void batadv_nc_node_release(struct batadv_nc_node *nc_node)
+ {
+-      struct batadv_nc_node *nc_node;
+-
+-      nc_node = container_of(rcu, struct batadv_nc_node, rcu);
+       batadv_orig_node_free_ref(nc_node->orig_node);
+-      kfree(nc_node);
++      kfree_rcu(nc_node, rcu);
+ }
+ /**
+- * batadv_nc_node_free_ref - decrements the nc node refcounter and possibly
+- * frees it
++ * batadv_nc_node_free_ref - decrement the nc node refcounter and possibly
++ *  release it
+  * @nc_node: the nc node to free
+  */
+ static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node)
+ {
+       if (atomic_dec_and_test(&nc_node->refcount))
+-              call_rcu(&nc_node->rcu, batadv_nc_node_free_rcu);
++              batadv_nc_node_release(nc_node);
+ }
+ /**
diff --git a/queue-4.4/batman-adv-drop-immediate-batadv_hard_iface-free-function.patch b/queue-4.4/batman-adv-drop-immediate-batadv_hard_iface-free-function.patch
new file mode 100644 (file)
index 0000000..93c4d6a
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:25 +0100
+Subject: batman-adv: Drop immediate batadv_hard_iface free function
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit b4d922cfc9c08318eeb77d53b7633740e6b0efb0 ]
+
+It is not allowed to free the memory of an object which is part of a list
+which is protected by rcu-read-side-critical sections without making sure
+that no other context is accessing the object anymore. This usually happens
+by removing the references to this object and then waiting until the rcu
+grace period is over and no one (allowedly) accesses it anymore.
+
+But the _now functions ignore this completely. They free the object
+directly even when a different context still tries to access it. This has
+to be avoided and thus these functions must be removed and all functions
+have to use batadv_hardif_free_ref.
+
+Fixes: 89652331c00f ("batman-adv: split tq information in neigh_node struct")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.h |   12 ------------
+ net/batman-adv/originator.c     |   14 +++++++-------
+ 2 files changed, 7 insertions(+), 19 deletions(-)
+
+--- a/net/batman-adv/hard-interface.h
++++ b/net/batman-adv/hard-interface.h
+@@ -75,18 +75,6 @@ batadv_hardif_free_ref(struct batadv_har
+               call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu);
+ }
+-/**
+- * batadv_hardif_free_ref_now - decrement the hard interface refcounter and
+- *  possibly free it (without rcu callback)
+- * @hard_iface: the hard interface to free
+- */
+-static inline void
+-batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface)
+-{
+-      if (atomic_dec_and_test(&hard_iface->refcount))
+-              batadv_hardif_free_rcu(&hard_iface->rcu);
+-}
+-
+ static inline struct batadv_hard_iface *
+ batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
+ {
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -189,16 +189,16 @@ void batadv_neigh_ifinfo_free_ref(struct
+ /**
+  * batadv_neigh_node_free_rcu - free the neigh_node
+- * @rcu: rcu pointer of the neigh_node
++ * batadv_neigh_node_release - release neigh_node from lists and queue for
++ *  free after rcu grace period
++ * @neigh_node: neigh neighbor to free
+  */
+-static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
++static void batadv_neigh_node_release(struct batadv_neigh_node *neigh_node)
+ {
+       struct hlist_node *node_tmp;
+-      struct batadv_neigh_node *neigh_node;
+       struct batadv_neigh_ifinfo *neigh_ifinfo;
+       struct batadv_algo_ops *bao;
+-      neigh_node = container_of(rcu, struct batadv_neigh_node, rcu);
+       bao = neigh_node->orig_node->bat_priv->bat_algo_ops;
+       hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
+@@ -209,9 +209,9 @@ static void batadv_neigh_node_free_rcu(s
+       if (bao->bat_neigh_free)
+               bao->bat_neigh_free(neigh_node);
+-      batadv_hardif_free_ref_now(neigh_node->if_incoming);
++      batadv_hardif_free_ref(neigh_node->if_incoming);
+-      kfree(neigh_node);
++      kfree_rcu(neigh_node, rcu);
+ }
+ /**
+@@ -222,7 +222,7 @@ static void batadv_neigh_node_free_rcu(s
+ void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
+ {
+       if (atomic_dec_and_test(&neigh_node->refcount))
+-              call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu);
++              batadv_neigh_node_release(neigh_node);
+ }
+ /**
diff --git a/queue-4.4/batman-adv-drop-immediate-batadv_neigh_node-free-function.patch b/queue-4.4/batman-adv-drop-immediate-batadv_neigh_node-free-function.patch
new file mode 100644 (file)
index 0000000..b838ca7
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:22 +0100
+Subject: batman-adv: Drop immediate batadv_neigh_node free function
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit 2baa753c276f27f8e844637561ad597867aa6fb6 ]
+
+It is not allowed to free the memory of an object which is part of a list
+which is protected by rcu-read-side-critical sections without making sure
+that no other context is accessing the object anymore. This usually happens
+by removing the references to this object and then waiting until the rcu
+grace period is over and no one (allowedly) accesses it anymore.
+
+But the _now functions ignore this completely. They free the object
+directly even when a different context still tries to access it. This has
+to be avoided and thus these functions must be removed and all functions
+have to use batadv_neigh_node_free_ref.
+
+Fixes: 89652331c00f ("batman-adv: split tq information in neigh_node struct")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/originator.c |   33 ++++++++++-----------------------
+ 1 file changed, 10 insertions(+), 23 deletions(-)
+
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -229,20 +229,8 @@ static void batadv_neigh_node_free_rcu(s
+ }
+ /**
+- * batadv_neigh_node_free_ref_now - decrement the neighbors refcounter
+- *  and possibly free it (without rcu callback)
+- * @neigh_node: neigh neighbor to free
+- */
+-static void
+-batadv_neigh_node_free_ref_now(struct batadv_neigh_node *neigh_node)
+-{
+-      if (atomic_dec_and_test(&neigh_node->refcount))
+-              batadv_neigh_node_free_rcu(&neigh_node->rcu);
+-}
+-
+-/**
+  * batadv_neigh_node_free_ref - decrement the neighbors refcounter
+- *  and possibly free it
++ *  and possibly release it
+  * @neigh_node: neigh neighbor to free
+  */
+ void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
+@@ -532,24 +520,23 @@ out:
+ }
+ /**
+- * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object
+- * @rcu: rcu pointer of the orig_ifinfo object
++ * batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for
++ *  free after rcu grace period
++ * @orig_ifinfo: the orig_ifinfo object to release
+  */
+-static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu)
++static void batadv_orig_ifinfo_release(struct batadv_orig_ifinfo *orig_ifinfo)
+ {
+-      struct batadv_orig_ifinfo *orig_ifinfo;
+       struct batadv_neigh_node *router;
+-      orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu);
+-
+       if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
+-              batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing);
++              batadv_hardif_free_ref(orig_ifinfo->if_outgoing);
+       /* this is the last reference to this object */
+       router = rcu_dereference_protected(orig_ifinfo->router, true);
+       if (router)
+-              batadv_neigh_node_free_ref_now(router);
+-      kfree(orig_ifinfo);
++              batadv_neigh_node_free_ref(router);
++
++      kfree_rcu(orig_ifinfo, rcu);
+ }
+ /**
+@@ -560,7 +547,7 @@ static void batadv_orig_ifinfo_free_rcu(
+ void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
+ {
+       if (atomic_dec_and_test(&orig_ifinfo->refcount))
+-              call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu);
++              batadv_orig_ifinfo_release(orig_ifinfo);
+ }
+ /**
diff --git a/queue-4.4/batman-adv-drop-immediate-batadv_orig_ifinfo-free-function.patch b/queue-4.4/batman-adv-drop-immediate-batadv_orig_ifinfo-free-function.patch
new file mode 100644 (file)
index 0000000..249d9e6
--- /dev/null
@@ -0,0 +1,139 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:21 +0100
+Subject: batman-adv: Drop immediate batadv_orig_ifinfo free function
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit deed96605f5695cb945e0b3d79429581857a2b9d ]
+
+It is not allowed to free the memory of an object which is part of a list
+which is protected by rcu-read-side-critical sections without making sure
+that no other context is accessing the object anymore. This usually happens
+by removing the references to this object and then waiting until the rcu
+grace period is over and no one (allowedly) accesses it anymore.
+
+But the _now functions ignore this completely. They free the object
+directly even when a different context still tries to access it. This has
+to be avoided and thus these functions must be removed and all functions
+have to use batadv_orig_ifinfo_free_ref.
+
+Fixes: 7351a4822d42 ("batman-adv: split out router from orig_node")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/originator.c |   59 +++++++++++++++++++++++---------------------
+ 1 file changed, 31 insertions(+), 28 deletions(-)
+
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -553,76 +553,79 @@ static void batadv_orig_ifinfo_free_rcu(
+ }
+ /**
+- * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
+- *  the orig_ifinfo (without rcu callback)
++ * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly release
++ *  the orig_ifinfo
+  * @orig_ifinfo: the orig_ifinfo object to release
+  */
+-static void
+-batadv_orig_ifinfo_free_ref_now(struct batadv_orig_ifinfo *orig_ifinfo)
++void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
+ {
+       if (atomic_dec_and_test(&orig_ifinfo->refcount))
+-              batadv_orig_ifinfo_free_rcu(&orig_ifinfo->rcu);
++              call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu);
+ }
+ /**
+- * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
+- *  the orig_ifinfo
+- * @orig_ifinfo: the orig_ifinfo object to release
++ * batadv_orig_node_free_rcu - free the orig_node
++ * @rcu: rcu pointer of the orig_node
+  */
+-void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
++static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
+ {
+-      if (atomic_dec_and_test(&orig_ifinfo->refcount))
+-              call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu);
++      struct batadv_orig_node *orig_node;
++
++      orig_node = container_of(rcu, struct batadv_orig_node, rcu);
++
++      batadv_mcast_purge_orig(orig_node);
++
++      batadv_frag_purge_orig(orig_node, NULL);
++
++      if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
++              orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
++
++      kfree(orig_node->tt_buff);
++      kfree(orig_node);
+ }
+-static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
++/**
++ * batadv_orig_node_release - release orig_node from lists and queue for
++ *  free after rcu grace period
++ * @orig_node: the orig node to free
++ */
++static void batadv_orig_node_release(struct batadv_orig_node *orig_node)
+ {
+       struct hlist_node *node_tmp;
+       struct batadv_neigh_node *neigh_node;
+-      struct batadv_orig_node *orig_node;
+       struct batadv_orig_ifinfo *orig_ifinfo;
+-      orig_node = container_of(rcu, struct batadv_orig_node, rcu);
+-
+       spin_lock_bh(&orig_node->neigh_list_lock);
+       /* for all neighbors towards this originator ... */
+       hlist_for_each_entry_safe(neigh_node, node_tmp,
+                                 &orig_node->neigh_list, list) {
+               hlist_del_rcu(&neigh_node->list);
+-              batadv_neigh_node_free_ref_now(neigh_node);
++              batadv_neigh_node_free_ref(neigh_node);
+       }
+       hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
+                                 &orig_node->ifinfo_list, list) {
+               hlist_del_rcu(&orig_ifinfo->list);
+-              batadv_orig_ifinfo_free_ref_now(orig_ifinfo);
++              batadv_orig_ifinfo_free_ref(orig_ifinfo);
+       }
+       spin_unlock_bh(&orig_node->neigh_list_lock);
+-      batadv_mcast_purge_orig(orig_node);
+-
+       /* Free nc_nodes */
+       batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
+-      batadv_frag_purge_orig(orig_node, NULL);
+-
+-      if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
+-              orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
+-
+-      kfree(orig_node->tt_buff);
+-      kfree(orig_node);
++      call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
+ }
+ /**
+  * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
+- * schedule an rcu callback for freeing it
++ *  release it
+  * @orig_node: the orig node to free
+  */
+ void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
+ {
+       if (atomic_dec_and_test(&orig_node->refcount))
+-              call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
++              batadv_orig_node_release(orig_node);
+ }
+ /**
diff --git a/queue-4.4/batman-adv-drop-immediate-neigh_ifinfo-free-function.patch b/queue-4.4/batman-adv-drop-immediate-neigh_ifinfo-free-function.patch
new file mode 100644 (file)
index 0000000..ace881c
--- /dev/null
@@ -0,0 +1,92 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:24 +0100
+Subject: batman-adv: Drop immediate neigh_ifinfo free function
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit ae3e1e36e3cb6c686a7a2725af20ca86aa46d62a ]
+
+It is not allowed to free the memory of an object which is part of a list
+which is protected by rcu-read-side-critical sections without making sure
+that no other context is accessing the object anymore. This usually happens
+by removing the references to this object and then waiting until the rcu
+grace period is over and no one (allowedly) accesses it anymore.
+
+But the _now functions ignore this completely. They free the object
+directly even when a different context still tries to access it. This has
+to be avoided and thus these functions must be removed and all functions
+have to use batadv_neigh_ifinfo_free_ref.
+
+Fixes: 89652331c00f ("batman-adv: split tq information in neigh_node struct")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/originator.c |   34 ++++++++++------------------------
+ 1 file changed, 10 insertions(+), 24 deletions(-)
+
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -163,42 +163,28 @@ err:
+ }
+ /**
+- * batadv_neigh_ifinfo_free_rcu - free the neigh_ifinfo object
+- * @rcu: rcu pointer of the neigh_ifinfo object
+- */
+-static void batadv_neigh_ifinfo_free_rcu(struct rcu_head *rcu)
+-{
+-      struct batadv_neigh_ifinfo *neigh_ifinfo;
+-
+-      neigh_ifinfo = container_of(rcu, struct batadv_neigh_ifinfo, rcu);
+-
+-      if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
+-              batadv_hardif_free_ref_now(neigh_ifinfo->if_outgoing);
+-
+-      kfree(neigh_ifinfo);
+-}
+-
+-/**
+- * batadv_neigh_ifinfo_free_now - decrement the refcounter and possibly free
+- *  the neigh_ifinfo (without rcu callback)
++ * batadv_neigh_ifinfo_release - release neigh_ifinfo from lists and queue for
++ *  free after rcu grace period
+  * @neigh_ifinfo: the neigh_ifinfo object to release
+  */
+ static void
+-batadv_neigh_ifinfo_free_ref_now(struct batadv_neigh_ifinfo *neigh_ifinfo)
++batadv_neigh_ifinfo_release(struct batadv_neigh_ifinfo *neigh_ifinfo)
+ {
+-      if (atomic_dec_and_test(&neigh_ifinfo->refcount))
+-              batadv_neigh_ifinfo_free_rcu(&neigh_ifinfo->rcu);
++      if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
++              batadv_hardif_free_ref(neigh_ifinfo->if_outgoing);
++
++      kfree_rcu(neigh_ifinfo, rcu);
+ }
+ /**
+- * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly free
++ * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly release
+  *  the neigh_ifinfo
+  * @neigh_ifinfo: the neigh_ifinfo object to release
+  */
+ void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo)
+ {
+       if (atomic_dec_and_test(&neigh_ifinfo->refcount))
+-              call_rcu(&neigh_ifinfo->rcu, batadv_neigh_ifinfo_free_rcu);
++              batadv_neigh_ifinfo_release(neigh_ifinfo);
+ }
+ /**
+@@ -217,7 +203,7 @@ static void batadv_neigh_node_free_rcu(s
+       hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
+                                 &neigh_node->ifinfo_list, list) {
+-              batadv_neigh_ifinfo_free_ref_now(neigh_ifinfo);
++              batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
+       }
+       if (bao->bat_neigh_free)
diff --git a/queue-4.4/batman-adv-drop-immediate-orig_node-free-function.patch b/queue-4.4/batman-adv-drop-immediate-orig_node-free-function.patch
new file mode 100644 (file)
index 0000000..81131dd
--- /dev/null
@@ -0,0 +1,111 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 5 Jan 2016 12:06:20 +0100
+Subject: batman-adv: Drop immediate orig_node free function
+
+From: Sven Eckelmann <sven@narfation.org>
+
+[ Upstream commit 42eff6a617e23b691f8e4467f4687ed7245a92db ]
+
+It is not allowed to free the memory of an object which is part of a list
+which is protected by rcu-read-side-critical sections without making sure
+that no other context is accessing the object anymore. This usually happens
+by removing the references to this object and then waiting until the rcu
+grace period is over and no one (allowedly) accesses it anymore.
+
+But the _now functions ignore this completely. They free the object
+directly even when a different context still tries to access it. This has
+to be avoided and thus these functions must be removed and all functions
+have to use batadv_orig_node_free_ref.
+
+Fixes: 72822225bd41 ("batman-adv: Fix rcu_barrier() miss due to double call_rcu() in TT code")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/originator.c        |   11 -----------
+ net/batman-adv/originator.h        |    1 -
+ net/batman-adv/translation-table.c |   28 +++++++++++++---------------
+ 3 files changed, 13 insertions(+), 27 deletions(-)
+
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -601,17 +601,6 @@ void batadv_orig_node_free_ref(struct ba
+               batadv_orig_node_release(orig_node);
+ }
+-/**
+- * batadv_orig_node_free_ref_now - decrement the orig node refcounter and
+- * possibly free it (without rcu callback)
+- * @orig_node: the orig node to free
+- */
+-void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node)
+-{
+-      if (atomic_dec_and_test(&orig_node->refcount))
+-              batadv_orig_node_free_rcu(&orig_node->rcu);
+-}
+-
+ void batadv_originator_free(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+--- a/net/batman-adv/originator.h
++++ b/net/batman-adv/originator.h
+@@ -38,7 +38,6 @@ int batadv_originator_init(struct batadv
+ void batadv_originator_free(struct batadv_priv *bat_priv);
+ void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
+ void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
+-void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
+ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
+                                             const u8 *addr);
+ struct batadv_neigh_node *
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -240,20 +240,6 @@ int batadv_tt_global_hash_count(struct b
+       return count;
+ }
+-static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
+-{
+-      struct batadv_tt_orig_list_entry *orig_entry;
+-
+-      orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
+-
+-      /* We are in an rcu callback here, therefore we cannot use
+-       * batadv_orig_node_free_ref() and its call_rcu():
+-       * An rcu_barrier() wouldn't wait for that to finish
+-       */
+-      batadv_orig_node_free_ref_now(orig_entry->orig_node);
+-      kfree(orig_entry);
+-}
+-
+ /**
+  * batadv_tt_local_size_mod - change the size by v of the local table identified
+  *  by vid
+@@ -349,13 +335,25 @@ static void batadv_tt_global_size_dec(st
+       batadv_tt_global_size_mod(orig_node, vid, -1);
+ }
++/**
++ * batadv_tt_orig_list_entry_release - release tt orig entry from lists and
++ *  queue for free after rcu grace period
++ * @orig_entry: tt orig entry to be free'd
++ */
++static void
++batadv_tt_orig_list_entry_release(struct batadv_tt_orig_list_entry *orig_entry)
++{
++      batadv_orig_node_free_ref(orig_entry->orig_node);
++      kfree_rcu(orig_entry, rcu);
++}
++
+ static void
+ batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
+ {
+       if (!atomic_dec_and_test(&orig_entry->refcount))
+               return;
+-      call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
++      batadv_tt_orig_list_entry_release(orig_entry);
+ }
+ /**
diff --git a/queue-4.4/bonding-prevent-ipv6-link-local-address-on-enslaved-devices.patch b/queue-4.4/bonding-prevent-ipv6-link-local-address-on-enslaved-devices.patch
new file mode 100644 (file)
index 0000000..1c4d9f0
--- /dev/null
@@ -0,0 +1,58 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Karl Heiss <kheiss@gmail.com>
+Date: Mon, 11 Jan 2016 08:28:43 -0500
+Subject: bonding: Prevent IPv6 link local address on enslaved devices
+
+From: Karl Heiss <kheiss@gmail.com>
+
+[ Upstream commit 03d84a5f83a67e692af00a3d3901e7820e3e84d5 ]
+
+Commit 1f718f0f4f97 ("bonding: populate neighbour's private on enslave")
+undoes the fix provided by commit c2edacf80e15 ("bonding / ipv6: no addrconf
+for slaves separately from master") by effectively setting the slave flag
+after the slave has been opened.  If the slave comes up quickly enough, it
+will go through the IPv6 addrconf before the slave flag has been set and
+will get a link local IPv6 address.
+
+In order to ensure that addrconf knows to ignore the slave devices on state
+change, set IFF_SLAVE before dev_open() during bonding enslavement.
+
+Fixes: 1f718f0f4f97 ("bonding: populate neighbour's private on enslave")
+Signed-off-by: Karl Heiss <kheiss@gmail.com>
+Signed-off-by: Jay Vosburgh <jay.vosburgh@canonical.com>
+Reviewed-by: Jarod Wilson <jarod@redhat.com>
+Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1207,7 +1207,6 @@ static int bond_master_upper_dev_link(st
+       err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
+       if (err)
+               return err;
+-      slave_dev->flags |= IFF_SLAVE;
+       rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
+       return 0;
+ }
+@@ -1465,6 +1464,9 @@ int bond_enslave(struct net_device *bond
+               }
+       }
++      /* set slave flag before open to prevent IPv6 addrconf */
++      slave_dev->flags |= IFF_SLAVE;
++
+       /* open the slave since the application closed it */
+       res = dev_open(slave_dev);
+       if (res) {
+@@ -1725,6 +1727,7 @@ err_close:
+       dev_close(slave_dev);
+ err_restore_mac:
++      slave_dev->flags &= ~IFF_SLAVE;
+       if (!bond->params.fail_over_mac ||
+           BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
+               /* XXX TODO - fom follow mode needs to change master's
diff --git a/queue-4.4/bridge-fix-lockdep-addr_list_lock-false-positive-splat.patch b/queue-4.4/bridge-fix-lockdep-addr_list_lock-false-positive-splat.patch
new file mode 100644 (file)
index 0000000..c63c9af
--- /dev/null
@@ -0,0 +1,133 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Fri, 15 Jan 2016 19:03:54 +0100
+Subject: bridge: fix lockdep addr_list_lock false positive splat
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+[ Upstream commit c6894dec8ea9ae05747124dce98b3b5c2e69b168 ]
+
+After promisc mode management was introduced a bridge device could do
+dev_set_promiscuity from its ndo_change_rx_flags() callback which in
+turn can be called after the bridge's addr_list_lock has been taken
+(e.g. by dev_uc_add). This causes a false positive lockdep splat because
+the port interfaces' addr_list_lock is taken when br_manage_promisc()
+runs after the bridge's addr list lock was already taken.
+To remove the false positive introduce a custom bridge addr_list_lock
+class and set it on bridge init.
+A simple way to reproduce this is with the following:
+$ brctl addbr br0
+$ ip l add l br0 br0.100 type vlan id 100
+$ ip l set br0 up
+$ ip l set br0.100 up
+$ echo 1 > /sys/class/net/br0/bridge/vlan_filtering
+$ brctl addif br0 eth0
+Splat:
+[   43.684325] =============================================
+[   43.684485] [ INFO: possible recursive locking detected ]
+[   43.684636] 4.4.0-rc8+ #54 Not tainted
+[   43.684755] ---------------------------------------------
+[   43.684906] brctl/1187 is trying to acquire lock:
+[   43.685047]  (_xmit_ETHER){+.....}, at: [<ffffffff8150169e>] dev_set_rx_mode+0x1e/0x40
+[   43.685460]  but task is already holding lock:
+[   43.685618]  (_xmit_ETHER){+.....}, at: [<ffffffff815072a7>] dev_uc_add+0x27/0x80
+[   43.686015]  other info that might help us debug this:
+[   43.686316]  Possible unsafe locking scenario:
+
+[   43.686743]        CPU0
+[   43.686967]        ----
+[   43.687197]   lock(_xmit_ETHER);
+[   43.687544]   lock(_xmit_ETHER);
+[   43.687886] *** DEADLOCK ***
+
+[   43.688438]  May be due to missing lock nesting notation
+
+[   43.688882] 2 locks held by brctl/1187:
+[   43.689134]  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff81510317>] rtnl_lock+0x17/0x20
+[   43.689852]  #1:  (_xmit_ETHER){+.....}, at: [<ffffffff815072a7>] dev_uc_add+0x27/0x80
+[   43.690575] stack backtrace:
+[   43.690970] CPU: 0 PID: 1187 Comm: brctl Not tainted 4.4.0-rc8+ #54
+[   43.691270] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.1-20150318_183358- 04/01/2014
+[   43.691770]  ffffffff826a25c0 ffff8800369fb8e0 ffffffff81360ceb ffffffff826a25c0
+[   43.692425]  ffff8800369fb9b8 ffffffff810d0466 ffff8800369fb968 ffffffff81537139
+[   43.693071]  ffff88003a08c880 0000000000000000 00000000ffffffff 0000000002080020
+[   43.693709] Call Trace:
+[   43.693931]  [<ffffffff81360ceb>] dump_stack+0x4b/0x70
+[   43.694199]  [<ffffffff810d0466>] __lock_acquire+0x1e46/0x1e90
+[   43.694483]  [<ffffffff81537139>] ? netlink_broadcast_filtered+0x139/0x3e0
+[   43.694789]  [<ffffffff8153b5da>] ? nlmsg_notify+0x5a/0xc0
+[   43.695064]  [<ffffffff810d10f5>] lock_acquire+0xe5/0x1f0
+[   43.695340]  [<ffffffff8150169e>] ? dev_set_rx_mode+0x1e/0x40
+[   43.695623]  [<ffffffff815edea5>] _raw_spin_lock_bh+0x45/0x80
+[   43.695901]  [<ffffffff8150169e>] ? dev_set_rx_mode+0x1e/0x40
+[   43.696180]  [<ffffffff8150169e>] dev_set_rx_mode+0x1e/0x40
+[   43.696460]  [<ffffffff8150189c>] dev_set_promiscuity+0x3c/0x50
+[   43.696750]  [<ffffffffa0586845>] br_port_set_promisc+0x25/0x50 [bridge]
+[   43.697052]  [<ffffffffa05869aa>] br_manage_promisc+0x8a/0xe0 [bridge]
+[   43.697348]  [<ffffffffa05826ee>] br_dev_change_rx_flags+0x1e/0x20 [bridge]
+[   43.697655]  [<ffffffff81501532>] __dev_set_promiscuity+0x132/0x1f0
+[   43.697943]  [<ffffffff81501672>] __dev_set_rx_mode+0x82/0x90
+[   43.698223]  [<ffffffff815072de>] dev_uc_add+0x5e/0x80
+[   43.698498]  [<ffffffffa05b3c62>] vlan_device_event+0x542/0x650 [8021q]
+[   43.698798]  [<ffffffff8109886d>] notifier_call_chain+0x5d/0x80
+[   43.699083]  [<ffffffff810988b6>] raw_notifier_call_chain+0x16/0x20
+[   43.699374]  [<ffffffff814f456e>] call_netdevice_notifiers_info+0x6e/0x80
+[   43.699678]  [<ffffffff814f4596>] call_netdevice_notifiers+0x16/0x20
+[   43.699973]  [<ffffffffa05872be>] br_add_if+0x47e/0x4c0 [bridge]
+[   43.700259]  [<ffffffffa058801e>] add_del_if+0x6e/0x80 [bridge]
+[   43.700548]  [<ffffffffa0588b5f>] br_dev_ioctl+0xaf/0xc0 [bridge]
+[   43.700836]  [<ffffffff8151a7ac>] dev_ifsioc+0x30c/0x3c0
+[   43.701106]  [<ffffffff8151aac9>] dev_ioctl+0xf9/0x6f0
+[   43.701379]  [<ffffffff81254345>] ? mntput_no_expire+0x5/0x450
+[   43.701665]  [<ffffffff812543ee>] ? mntput_no_expire+0xae/0x450
+[   43.701947]  [<ffffffff814d7b02>] sock_do_ioctl+0x42/0x50
+[   43.702219]  [<ffffffff814d8175>] sock_ioctl+0x1e5/0x290
+[   43.702500]  [<ffffffff81242d0b>] do_vfs_ioctl+0x2cb/0x5c0
+[   43.702771]  [<ffffffff81243079>] SyS_ioctl+0x79/0x90
+[   43.703033]  [<ffffffff815eebb6>] entry_SYSCALL_64_fastpath+0x16/0x7a
+
+CC: Vlad Yasevich <vyasevic@redhat.com>
+CC: Stephen Hemminger <stephen@networkplumber.org>
+CC: Bridge list <bridge@lists.linux-foundation.org>
+CC: Andy Gospodarek <gospo@cumulusnetworks.com>
+CC: Roopa Prabhu <roopa@cumulusnetworks.com>
+Fixes: 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.")
+Reported-by: Andy Gospodarek <gospo@cumulusnetworks.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_device.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/net/bridge/br_device.c
++++ b/net/bridge/br_device.c
+@@ -28,6 +28,8 @@
+ const struct nf_br_ops __rcu *nf_br_ops __read_mostly;
+ EXPORT_SYMBOL_GPL(nf_br_ops);
++static struct lock_class_key bridge_netdev_addr_lock_key;
++
+ /* net device transmit always called with BH disabled */
+ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+@@ -87,6 +89,11 @@ out:
+       return NETDEV_TX_OK;
+ }
++static void br_set_lockdep_class(struct net_device *dev)
++{
++      lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key);
++}
++
+ static int br_dev_init(struct net_device *dev)
+ {
+       struct net_bridge *br = netdev_priv(dev);
+@@ -99,6 +106,7 @@ static int br_dev_init(struct net_device
+       err = br_vlan_init(br);
+       if (err)
+               free_percpu(br->stats);
++      br_set_lockdep_class(dev);
+       return err;
+ }
diff --git a/queue-4.4/dwc_eth_qos-fix-dma-address-for-multi-fragment-skbs.patch b/queue-4.4/dwc_eth_qos-fix-dma-address-for-multi-fragment-skbs.patch
new file mode 100644 (file)
index 0000000..0ecefa3
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Lars Persson <lars.persson@axis.com>
+Date: Tue, 12 Jan 2016 15:28:13 +0100
+Subject: dwc_eth_qos: Fix dma address for multi-fragment skbs
+
+From: Lars Persson <lars.persson@axis.com>
+
+[ Upstream commit d461873272169a3fc3a8d155d7b1c92e9d97b419 ]
+
+The offset inside the fragment was not used for the dma address and
+silent data corruption resulted because TSO makes the checksum match.
+
+Fixes: 077742dac2c7 ("dwc_eth_qos: Add support for Synopsys DWC Ethernet QoS")
+Signed-off-by: Lars Persson <larper@axis.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/synopsys/dwc_eth_qos.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c
++++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c
+@@ -2107,7 +2107,7 @@ static int dwceqos_tx_frags(struct sk_bu
+                       dd = &lp->tx_descs[lp->tx_next];
+                       /* Set DMA Descriptor fields */
+-                      dd->des0 = dma_handle;
++                      dd->des0 = dma_handle + consumed_size;
+                       dd->des1 = 0;
+                       dd->des2 = dma_size;
diff --git a/queue-4.4/ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch b/queue-4.4/ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch
new file mode 100644 (file)
index 0000000..5928c66
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 8 Jan 2016 09:35:51 -0800
+Subject: ipv6: tcp: add rcu locking in tcp_v6_send_synack()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 3e4006f0b86a5ae5eb0e8215f9a9e1db24506977 ]
+
+When first SYNACK is sent, we already hold rcu_read_lock(), but this
+is not true if a SYNACK is retransmitted, as a timer (soft) interrupt
+does not hold rcu_read_lock()
+
+Fixes: 45f6fad84cc30 ("ipv6: add complete rcu protection around np->opt")
+Reported-by: Dave Jones <davej@codemonkey.org.uk>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/tcp_ipv6.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -462,8 +462,10 @@ static int tcp_v6_send_synack(const stru
+               if (np->repflow && ireq->pktopts)
+                       fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
++              rcu_read_lock();
+               err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
+                              np->tclass);
++              rcu_read_unlock();
+               err = net_xmit_eval(err);
+       }
diff --git a/queue-4.4/ipv6-update-skb-csum-when-ce-mark-is-propagated.patch b/queue-4.4/ipv6-update-skb-csum-when-ce-mark-is-propagated.patch
new file mode 100644 (file)
index 0000000..986fa22
--- /dev/null
@@ -0,0 +1,74 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 15 Jan 2016 04:56:56 -0800
+Subject: ipv6: update skb->csum when CE mark is propagated
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 34ae6a1aa0540f0f781dd265366036355fdc8930 ]
+
+When a tunnel decapsulates the outer header, it has to comply
+with RFC 6080 and eventually propagate CE mark into inner header.
+
+It turns out IP6_ECN_set_ce() does not correctly update skb->csum
+for CHECKSUM_COMPLETE packets, triggering infamous "hw csum failure"
+messages and stack traces.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Acked-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>
+---
+ include/net/inet_ecn.h       |   19 ++++++++++++++++---
+ net/ipv6/xfrm6_mode_tunnel.c |    2 +-
+ 2 files changed, 17 insertions(+), 4 deletions(-)
+
+--- a/include/net/inet_ecn.h
++++ b/include/net/inet_ecn.h
+@@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsign
+ struct ipv6hdr;
+-static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
++/* Note:
++ * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE,
++ * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE
++ * In IPv6 case, no checksum compensates the change in IPv6 header,
++ * so we have to update skb->csum.
++ */
++static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
+ {
++      __be32 from, to;
++
+       if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
+               return 0;
+-      *(__be32*)iph |= htonl(INET_ECN_CE << 20);
++
++      from = *(__be32 *)iph;
++      to = from | htonl(INET_ECN_CE << 20);
++      *(__be32 *)iph = to;
++      if (skb->ip_summed == CHECKSUM_COMPLETE)
++              skb->csum = csum_add(csum_sub(skb->csum, from), to);
+       return 1;
+ }
+@@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct
+       case cpu_to_be16(ETH_P_IPV6):
+               if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
+                   skb_tail_pointer(skb))
+-                      return IP6_ECN_set_ce(ipv6_hdr(skb));
++                      return IP6_ECN_set_ce(skb, ipv6_hdr(skb));
+               break;
+       }
+--- a/net/ipv6/xfrm6_mode_tunnel.c
++++ b/net/ipv6/xfrm6_mode_tunnel.c
+@@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate
+       struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
+       if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
+-              IP6_ECN_set_ce(inner_iph);
++              IP6_ECN_set_ce(skb, inner_iph);
+ }
+ /* Add encapsulation header.
diff --git a/queue-4.4/net-bpf-reject-invalid-shifts.patch b/queue-4.4/net-bpf-reject-invalid-shifts.patch
new file mode 100644 (file)
index 0000000..01b0efc
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Rabin Vincent <rabin@rab.in>
+Date: Tue, 12 Jan 2016 20:17:08 +0100
+Subject: net: bpf: reject invalid shifts
+
+From: Rabin Vincent <rabin@rab.in>
+
+[ Upstream commit 229394e8e62a4191d592842cf67e80c62a492937 ]
+
+On ARM64, a BUG() is triggered in the eBPF JIT if a filter with a
+constant shift that can't be encoded in the immediate field of the
+UBFM/SBFM instructions is passed to the JIT.  Since these shifts
+amounts, which are negative or >= regsize, are invalid, reject them in
+the eBPF verifier and the classic BPF filter checker, for all
+architectures.
+
+Signed-off-by: Rabin Vincent <rabin@rab.in>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/verifier.c |   10 ++++++++++
+ net/core/filter.c     |    5 +++++
+ 2 files changed, 15 insertions(+)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1121,6 +1121,16 @@ static int check_alu_op(struct verifier_
+                       return -EINVAL;
+               }
++              if ((opcode == BPF_LSH || opcode == BPF_RSH ||
++                   opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) {
++                      int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32;
++
++                      if (insn->imm < 0 || insn->imm >= size) {
++                              verbose("invalid shift %d\n", insn->imm);
++                              return -EINVAL;
++                      }
++              }
++
+               /* pattern match 'bpf_add Rx, imm' instruction */
+               if (opcode == BPF_ADD && BPF_CLASS(insn->code) == BPF_ALU64 &&
+                   regs[insn->dst_reg].type == FRAME_PTR &&
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -777,6 +777,11 @@ static int bpf_check_classic(const struc
+                       if (ftest->k == 0)
+                               return -EINVAL;
+                       break;
++              case BPF_ALU | BPF_LSH | BPF_K:
++              case BPF_ALU | BPF_RSH | BPF_K:
++                      if (ftest->k >= 32)
++                              return -EINVAL;
++                      break;
+               case BPF_LD | BPF_MEM:
+               case BPF_LDX | BPF_MEM:
+               case BPF_ST:
diff --git a/queue-4.4/net-mlx5_core-fix-trimming-down-irq-number.patch b/queue-4.4/net-mlx5_core-fix-trimming-down-irq-number.patch
new file mode 100644 (file)
index 0000000..5cf9b9e
--- /dev/null
@@ -0,0 +1,124 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Doron Tsur <doront@mellanox.com>
+Date: Sun, 17 Jan 2016 11:25:47 +0200
+Subject: net/mlx5_core: Fix trimming down IRQ number
+
+From: Doron Tsur <doront@mellanox.com>
+
+[ Upstream commit 0b6e26ce89391327d955a756a7823272238eb867 ]
+
+With several ConnectX-4 cards installed on a server, one may receive
+irqn > 255 from the kernel API, which we mistakenly trim to 8bit.
+
+This causes EQ creation failure with the following stack trace:
+[<ffffffff812a11f4>] dump_stack+0x48/0x64
+[<ffffffff810ace21>] __setup_irq+0x3a1/0x4f0
+[<ffffffff810ad7e0>] request_threaded_irq+0x120/0x180
+[<ffffffffa0923660>] ? mlx5_eq_int+0x450/0x450 [mlx5_core]
+[<ffffffffa0922f64>] mlx5_create_map_eq+0x1e4/0x2b0 [mlx5_core]
+[<ffffffffa091de01>] alloc_comp_eqs+0xb1/0x180 [mlx5_core]
+[<ffffffffa091ea99>] mlx5_dev_init+0x5e9/0x6e0 [mlx5_core]
+[<ffffffffa091ec29>] init_one+0x99/0x1c0 [mlx5_core]
+[<ffffffff812e2afc>] local_pci_probe+0x4c/0xa0
+
+Fixing it by changing of the irqn type from u8 to unsigned int to
+support values > 255
+
+Fixes: 61d0e73e0a5a ('net/mlx5_core: Use the the real irqn in eq->irqn')
+Reported-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: Doron Tsur <doront@mellanox.com>
+Signed-off-by: Matan Barak <matanb@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/mlx5/cq.c                   |    2 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c |    6 +++---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c    |    3 ++-
+ include/linux/mlx5/cq.h                           |    2 +-
+ include/linux/mlx5/driver.h                       |    5 +++--
+ 5 files changed, 10 insertions(+), 8 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -756,7 +756,7 @@ struct ib_cq *mlx5_ib_create_cq(struct i
+       int uninitialized_var(index);
+       int uninitialized_var(inlen);
+       int cqe_size;
+-      int irqn;
++      unsigned int irqn;
+       int eqn;
+       int err;
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -746,7 +746,7 @@ static int mlx5e_create_cq(struct mlx5e_
+       struct mlx5_core_dev *mdev = priv->mdev;
+       struct mlx5_core_cq *mcq = &cq->mcq;
+       int eqn_not_used;
+-      int irqn;
++      unsigned int irqn;
+       int err;
+       u32 i;
+@@ -800,7 +800,7 @@ static int mlx5e_enable_cq(struct mlx5e_
+       void *in;
+       void *cqc;
+       int inlen;
+-      int irqn_not_used;
++      unsigned int irqn_not_used;
+       int eqn;
+       int err;
+@@ -1504,7 +1504,7 @@ static int mlx5e_create_drop_cq(struct m
+       struct mlx5_core_dev *mdev = priv->mdev;
+       struct mlx5_core_cq *mcq = &cq->mcq;
+       int eqn_not_used;
+-      int irqn;
++      unsigned int irqn;
+       int err;
+       err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -568,7 +568,8 @@ static void mlx5_irq_clear_affinity_hint
+               mlx5_irq_clear_affinity_hint(mdev, i);
+ }
+-int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn)
++int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
++                  unsigned int *irqn)
+ {
+       struct mlx5_eq_table *table = &dev->priv.eq_table;
+       struct mlx5_eq *eq, *n;
+--- a/include/linux/mlx5/cq.h
++++ b/include/linux/mlx5/cq.h
+@@ -45,7 +45,7 @@ struct mlx5_core_cq {
+       atomic_t                refcount;
+       struct completion       free;
+       unsigned                vector;
+-      int                     irqn;
++      unsigned int            irqn;
+       void (*comp)            (struct mlx5_core_cq *);
+       void (*event)           (struct mlx5_core_cq *, enum mlx5_event);
+       struct mlx5_uar        *uar;
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -303,7 +303,7 @@ struct mlx5_eq {
+       u32                     cons_index;
+       struct mlx5_buf         buf;
+       int                     size;
+-      u8                      irqn;
++      unsigned int            irqn;
+       u8                      eqn;
+       int                     nent;
+       u64                     mask;
+@@ -762,7 +762,8 @@ int mlx5_create_map_eq(struct mlx5_core_
+ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
+ int mlx5_start_eqs(struct mlx5_core_dev *dev);
+ int mlx5_stop_eqs(struct mlx5_core_dev *dev);
+-int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn);
++int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
++                  unsigned int *irqn);
+ int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
+ int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
diff --git a/queue-4.4/net-pktgen-fix-null-ptr-deref-in-skb-allocation.patch b/queue-4.4/net-pktgen-fix-null-ptr-deref-in-skb-allocation.patch
new file mode 100644 (file)
index 0000000..7cbc3bc
--- /dev/null
@@ -0,0 +1,33 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: John Fastabend <john.fastabend@gmail.com>
+Date: Sun, 10 Jan 2016 21:38:44 -0800
+Subject: net: pktgen: fix null ptr deref in skb allocation
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit 3de03596dfeee48bc803c1d1a6daf60a459929f3 ]
+
+Fix possible null pointer dereference that may occur when calling
+skb_reserve() on a null skb.
+
+Fixes: 879c7220e82 ("net: pktgen: Observe needed_headroom of the device")
+Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/pktgen.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -2787,7 +2787,9 @@ static struct sk_buff *pktgen_alloc_skb(
+       } else {
+                skb = __netdev_alloc_skb(dev, size, GFP_NOWAIT);
+       }
+-      skb_reserve(skb, LL_RESERVED_SPACE(dev));
++
++      if (likely(skb))
++              skb_reserve(skb, LL_RESERVED_SPACE(dev));
+       return skb;
+ }
diff --git a/queue-4.4/net-preserve-ip-control-block-during-gso-segmentation.patch b/queue-4.4/net-preserve-ip-control-block-during-gso-segmentation.patch
new file mode 100644 (file)
index 0000000..baee902
--- /dev/null
@@ -0,0 +1,107 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Konstantin Khlebnikov <koct9i@gmail.com>
+Date: Fri, 8 Jan 2016 15:21:46 +0300
+Subject: net: preserve IP control block during GSO segmentation
+
+From: Konstantin Khlebnikov <koct9i@gmail.com>
+
+[ Upstream commit 9207f9d45b0ad071baa128e846d7e7ed85016df3 ]
+
+Skb_gso_segment() uses skb control block during segmentation.
+This patch adds 32-bytes room for previous control block which
+will be copied into all resulting segments.
+
+This patch fixes kernel crash during fragmenting forwarded packets.
+Fragmentation requires valid IP CB in skb for clearing ip options.
+Also patch removes custom save/restore in ovs code, now it's redundant.
+
+Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com>
+Link: http://lkml.kernel.org/r/CALYGNiP-0MZ-FExV2HutTvE9U-QQtkKSoE--KN=JQE5STYsjAA@mail.gmail.com
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skbuff.h     |    3 ++-
+ net/core/dev.c             |    5 +++++
+ net/ipv4/ip_output.c       |    1 +
+ net/openvswitch/datapath.c |    5 +----
+ net/xfrm/xfrm_output.c     |    2 ++
+ 5 files changed, 11 insertions(+), 5 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -3446,7 +3446,8 @@ struct skb_gso_cb {
+       int     encap_level;
+       __u16   csum_start;
+ };
+-#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb)
++#define SKB_SGO_CB_OFFSET     32
++#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET))
+ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
+ {
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2542,6 +2542,8 @@ static inline bool skb_needs_check(struc
+  *
+  *    It may return NULL if the skb requires no segmentation.  This is
+  *    only possible when GSO is used for verifying header integrity.
++ *
++ *    Segmentation preserves SKB_SGO_CB_OFFSET bytes of previous skb cb.
+  */
+ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
+                                 netdev_features_t features, bool tx_path)
+@@ -2556,6 +2558,9 @@ struct sk_buff *__skb_gso_segment(struct
+                       return ERR_PTR(err);
+       }
++      BUILD_BUG_ON(SKB_SGO_CB_OFFSET +
++                   sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb));
++
+       SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
+       SKB_GSO_CB(skb)->encap_level = 0;
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -240,6 +240,7 @@ static int ip_finish_output_gso(struct n
+        * from host network stack.
+        */
+       features = netif_skb_features(skb);
++      BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
+       segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+       if (IS_ERR_OR_NULL(segs)) {
+               kfree_skb(skb);
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -336,12 +336,10 @@ static int queue_gso_packets(struct data
+       unsigned short gso_type = skb_shinfo(skb)->gso_type;
+       struct sw_flow_key later_key;
+       struct sk_buff *segs, *nskb;
+-      struct ovs_skb_cb ovs_cb;
+       int err;
+-      ovs_cb = *OVS_CB(skb);
++      BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET);
+       segs = __skb_gso_segment(skb, NETIF_F_SG, false);
+-      *OVS_CB(skb) = ovs_cb;
+       if (IS_ERR(segs))
+               return PTR_ERR(segs);
+       if (segs == NULL)
+@@ -359,7 +357,6 @@ static int queue_gso_packets(struct data
+       /* Queue all of the segments. */
+       skb = segs;
+       do {
+-              *OVS_CB(skb) = ovs_cb;
+               if (gso_type & SKB_GSO_UDP && skb != segs)
+                       key = &later_key;
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *n
+ {
+       struct sk_buff *segs;
++      BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
++      BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET);
+       segs = skb_gso_segment(skb, 0);
+       kfree_skb(skb);
+       if (IS_ERR(segs))
diff --git a/queue-4.4/net-sctp-prevent-writes-to-cookie_hmac_alg-from-accessing-invalid-memory.patch b/queue-4.4/net-sctp-prevent-writes-to-cookie_hmac_alg-from-accessing-invalid-memory.patch
new file mode 100644 (file)
index 0000000..242216f
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Thu, 7 Jan 2016 14:52:43 -0500
+Subject: net: sctp: prevent writes to cookie_hmac_alg from accessing invalid memory
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+[ Upstream commit 320f1a4a175e7cd5d3f006f92b4d4d3e2cbb7bb5 ]
+
+proc_dostring() needs an initialized destination string, while the one
+provided in proc_sctp_do_hmac_alg() contains stack garbage.
+
+Thus, writing to cookie_hmac_alg would strlen() that garbage and end up
+accessing invalid memory.
+
+Fixes: 3c68198e7 ("sctp: Make hmac algorithm selection for cookie generation dynamic")
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/sysctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -320,7 +320,7 @@ static int proc_sctp_do_hmac_alg(struct
+       struct ctl_table tbl;
+       bool changed = false;
+       char *none = "none";
+-      char tmp[8];
++      char tmp[8] = {0};
+       int ret;
+       memset(&tbl, 0, sizeof(struct ctl_table));
diff --git a/queue-4.4/phonet-properly-unshare-skbs-in-phonet_rcv.patch b/queue-4.4/phonet-properly-unshare-skbs-in-phonet_rcv.patch
new file mode 100644 (file)
index 0000000..9c9bae3
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 12 Jan 2016 08:58:00 -0800
+Subject: phonet: properly unshare skbs in phonet_rcv()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7aaed57c5c2890634cfadf725173c7c68ea4cb4f ]
+
+Ivaylo Dimitrov reported a regression caused by commit 7866a621043f
+("dev: add per net_device packet type chains").
+
+skb->dev becomes NULL and we crash in __netif_receive_skb_core().
+
+Before above commit, different kind of bugs or corruptions could happen
+without major crash.
+
+But the root cause is that phonet_rcv() can queue skb without checking
+if skb is shared or not.
+
+Many thanks to Ivaylo Dimitrov for his help, diagnosis and tests.
+
+Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Remi Denis-Courmont <courmisch@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/phonet/af_phonet.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/phonet/af_phonet.c
++++ b/net/phonet/af_phonet.c
+@@ -377,6 +377,10 @@ static int phonet_rcv(struct sk_buff *sk
+       struct sockaddr_pn sa;
+       u16 len;
++      skb = skb_share_check(skb, GFP_ATOMIC);
++      if (!skb)
++              return NET_RX_DROP;
++
+       /* check we have at least a full Phonet header */
+       if (!pskb_pull(skb, sizeof(struct phonethdr)))
+               goto out;
diff --git a/queue-4.4/sched-cls_flower-set-key-address-type-when-present.patch b/queue-4.4/sched-cls_flower-set-key-address-type-when-present.patch
new file mode 100644 (file)
index 0000000..2ff82db
--- /dev/null
@@ -0,0 +1,61 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+Date: Sun, 10 Jan 2016 11:47:01 -0500
+Subject: sched,cls_flower: set key address type when present
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 66530bdf85eb1d72a0c399665e09a2c2298501c6 ]
+
+only when user space passes the addresses should we consider their
+presence
+
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Acked-by: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/cls_flower.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -252,23 +252,28 @@ static int fl_set_key(struct net *net, s
+       fl_set_key_val(tb, key->eth.src, TCA_FLOWER_KEY_ETH_SRC,
+                      mask->eth.src, TCA_FLOWER_KEY_ETH_SRC_MASK,
+                      sizeof(key->eth.src));
++
+       fl_set_key_val(tb, &key->basic.n_proto, TCA_FLOWER_KEY_ETH_TYPE,
+                      &mask->basic.n_proto, TCA_FLOWER_UNSPEC,
+                      sizeof(key->basic.n_proto));
++
+       if (key->basic.n_proto == htons(ETH_P_IP) ||
+           key->basic.n_proto == htons(ETH_P_IPV6)) {
+               fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
+                              &mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
+                              sizeof(key->basic.ip_proto));
+       }
+-      if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
++
++      if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
++              key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+               fl_set_key_val(tb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
+                              &mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
+                              sizeof(key->ipv4.src));
+               fl_set_key_val(tb, &key->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST,
+                              &mask->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST_MASK,
+                              sizeof(key->ipv4.dst));
+-      } else if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
++      } else if (tb[TCA_FLOWER_KEY_IPV6_SRC] || tb[TCA_FLOWER_KEY_IPV6_DST]) {
++              key->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+               fl_set_key_val(tb, &key->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC,
+                              &mask->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC_MASK,
+                              sizeof(key->ipv6.src));
+@@ -276,6 +281,7 @@ static int fl_set_key(struct net *net, s
+                              &mask->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST_MASK,
+                              sizeof(key->ipv6.dst));
+       }
++
+       if (key->basic.ip_proto == IPPROTO_TCP) {
+               fl_set_key_val(tb, &key->tp.src, TCA_FLOWER_KEY_TCP_SRC,
+                              &mask->tp.src, TCA_FLOWER_UNSPEC,
index ec86b1b72c6ef2f1d5abc5e835cf66e09177bab3..fd73bf0df46b393e97ac372e525e913f30dc4361 100644 (file)
@@ -33,3 +33,27 @@ rtlwifi-fix-memory-leak-for-usb-device.patch
 usb-cp210x-add-id-for-elv-marble-sound-board-1.patch
 usb-core-lpm-fix-usb3_hardware_lpm-sysfs-node.patch
 xhci-refuse-loading-if-nousb-is-used.patch
+unix-properly-account-for-fds-passed-over-unix-sockets.patch
+vxlan-fix-test-which-detect-duplicate-vxlan-iface.patch
+net-sctp-prevent-writes-to-cookie_hmac_alg-from-accessing-invalid-memory.patch
+ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch
+tcp_yeah-don-t-set-ssthresh-below-2.patch
+sched-cls_flower-set-key-address-type-when-present.patch
+net-pktgen-fix-null-ptr-deref-in-skb-allocation.patch
+udp-disallow-ufo-for-sockets-with-so_no_check-option.patch
+net-preserve-ip-control-block-during-gso-segmentation.patch
+bonding-prevent-ipv6-link-local-address-on-enslaved-devices.patch
+dwc_eth_qos-fix-dma-address-for-multi-fragment-skbs.patch
+phonet-properly-unshare-skbs-in-phonet_rcv.patch
+net-bpf-reject-invalid-shifts.patch
+ipv6-update-skb-csum-when-ce-mark-is-propagated.patch
+bridge-fix-lockdep-addr_list_lock-false-positive-splat.patch
+net-mlx5_core-fix-trimming-down-irq-number.patch
+team-replace-rcu_read_lock-with-a-mutex-in-team_vlan_rx_kill_vid.patch
+batman-adv-avoid-recursive-call_rcu-for-batadv_bla_claim.patch
+batman-adv-avoid-recursive-call_rcu-for-batadv_nc_node.patch
+batman-adv-drop-immediate-batadv_orig_ifinfo-free-function.patch
+batman-adv-drop-immediate-batadv_neigh_node-free-function.patch
+batman-adv-drop-immediate-neigh_ifinfo-free-function.patch
+batman-adv-drop-immediate-batadv_hard_iface-free-function.patch
+batman-adv-drop-immediate-orig_node-free-function.patch
diff --git a/queue-4.4/tcp_yeah-don-t-set-ssthresh-below-2.patch b/queue-4.4/tcp_yeah-don-t-set-ssthresh-below-2.patch
new file mode 100644 (file)
index 0000000..15bd1c1
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Neal Cardwell <ncardwell@google.com>
+Date: Mon, 11 Jan 2016 13:42:43 -0500
+Subject: tcp_yeah: don't set ssthresh below 2
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 83d15e70c4d8909d722c0d64747d8fb42e38a48f ]
+
+For tcp_yeah, use an ssthresh floor of 2, the same floor used by Reno
+and CUBIC, per RFC 5681 (equation 4).
+
+tcp_yeah_ssthresh() was sometimes returning a 0 or negative ssthresh
+value if the intended reduction is as big or bigger than the current
+cwnd. Congestion control modules should never return a zero or
+negative ssthresh. A zero ssthresh generally results in a zero cwnd,
+causing the connection to stall. A negative ssthresh value will be
+interpreted as a u32 and will set a target cwnd for PRR near 4
+billion.
+
+Oleksandr Natalenko reported that a system using tcp_yeah with ECN
+could see a warning about a prior_cwnd of 0 in
+tcp_cwnd_reduction(). Testing verified that this was due to
+tcp_yeah_ssthresh() misbehaving in this way.
+
+Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_yeah.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp_yeah.c
++++ b/net/ipv4/tcp_yeah.c
+@@ -219,7 +219,7 @@ static u32 tcp_yeah_ssthresh(struct sock
+       yeah->fast_count = 0;
+       yeah->reno_count = max(yeah->reno_count>>1, 2U);
+-      return tp->snd_cwnd - reduction;
++      return max_t(int, tp->snd_cwnd - reduction, 2);
+ }
+ static struct tcp_congestion_ops tcp_yeah __read_mostly = {
diff --git a/queue-4.4/team-replace-rcu_read_lock-with-a-mutex-in-team_vlan_rx_kill_vid.patch b/queue-4.4/team-replace-rcu_read_lock-with-a-mutex-in-team_vlan_rx_kill_vid.patch
new file mode 100644 (file)
index 0000000..07ccc41
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Ido Schimmel <idosch@mellanox.com>
+Date: Mon, 18 Jan 2016 17:30:22 +0200
+Subject: team: Replace rcu_read_lock with a mutex in team_vlan_rx_kill_vid
+
+From: Ido Schimmel <idosch@mellanox.com>
+
+[ Upstream commit 60a6531bfe49555581ccd65f66a350cc5693fcde ]
+
+We can't be within an RCU read-side critical section when deleting
+VLANs, as underlying drivers might sleep during the hardware operation.
+Therefore, replace the RCU critical section with a mutex. This is
+consistent with team_vlan_rx_add_vid.
+
+Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device")
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: Ido Schimmel <idosch@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/team/team.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -1845,10 +1845,10 @@ static int team_vlan_rx_kill_vid(struct
+       struct team *team = netdev_priv(dev);
+       struct team_port *port;
+-      rcu_read_lock();
+-      list_for_each_entry_rcu(port, &team->port_list, list)
++      mutex_lock(&team->lock);
++      list_for_each_entry(port, &team->port_list, list)
+               vlan_vid_del(port->dev, proto, vid);
+-      rcu_read_unlock();
++      mutex_unlock(&team->lock);
+       return 0;
+ }
diff --git a/queue-4.4/udp-disallow-ufo-for-sockets-with-so_no_check-option.patch b/queue-4.4/udp-disallow-ufo-for-sockets-with-so_no_check-option.patch
new file mode 100644 (file)
index 0000000..b3c603b
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= <mkubecek@suse.cz>
+Date: Mon, 11 Jan 2016 07:50:30 +0100
+Subject: udp: disallow UFO for sockets with SO_NO_CHECK option
+
+From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= <mkubecek@suse.cz>
+
+[ Upstream commit 40ba330227ad00b8c0cdf2f425736ff9549cc423 ]
+
+Commit acf8dd0a9d0b ("udp: only allow UFO for packets from SOCK_DGRAM
+sockets") disallows UFO for packets sent from raw sockets. We need to do
+the same also for SOCK_DGRAM sockets with SO_NO_CHECK options, even if
+for a bit different reason: while such socket would override the
+CHECKSUM_PARTIAL set by ip_ufo_append_data(), gso_size is still set and
+bad offloading flags warning is triggered in __skb_gso_segment().
+
+In the IPv6 case, SO_NO_CHECK option is ignored but we need to disallow
+UFO for packets sent by sockets with UDP_NO_CHECK6_TX option.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Tested-by: Shannon Nelson <shannon.nelson@intel.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_output.c  |    2 +-
+ net/ipv6/ip6_output.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -921,7 +921,7 @@ static int __ip_append_data(struct sock
+       if (((length > mtu) || (skb && skb_is_gso(skb))) &&
+           (sk->sk_protocol == IPPROTO_UDP) &&
+           (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
+-          (sk->sk_type == SOCK_DGRAM)) {
++          (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) {
+               err = ip_ufo_append_data(sk, queue, getfrag, from, length,
+                                        hh_len, fragheaderlen, transhdrlen,
+                                        maxfraglen, flags);
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1353,7 +1353,7 @@ emsgsize:
+            (skb && skb_is_gso(skb))) &&
+           (sk->sk_protocol == IPPROTO_UDP) &&
+           (rt->dst.dev->features & NETIF_F_UFO) &&
+-          (sk->sk_type == SOCK_DGRAM)) {
++          (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
+               err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
+                                         hh_len, fragheaderlen,
+                                         transhdrlen, mtu, flags, fl6);
diff --git a/queue-4.4/unix-properly-account-for-fds-passed-over-unix-sockets.patch b/queue-4.4/unix-properly-account-for-fds-passed-over-unix-sockets.patch
new file mode 100644 (file)
index 0000000..e36ae0a
--- /dev/null
@@ -0,0 +1,136 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: willy tarreau <w@1wt.eu>
+Date: Sun, 10 Jan 2016 07:54:56 +0100
+Subject: unix: properly account for FDs passed over unix sockets
+
+From: willy tarreau <w@1wt.eu>
+
+[ Upstream commit 712f4aad406bb1ed67f3f98d04c044191f0ff593 ]
+
+It is possible for a process to allocate and accumulate far more FDs than
+the process' limit by sending them over a unix socket then closing them
+to keep the process' fd count low.
+
+This change addresses this problem by keeping track of the number of FDs
+in flight per user and preventing non-privileged processes from having
+more FDs in flight than their configured FD limit.
+
+Reported-by: socketpair@gmail.com
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Mitigates: CVE-2013-4312 (Linux 2.0+)
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/sched.h |    1 +
+ net/unix/af_unix.c    |   24 ++++++++++++++++++++----
+ net/unix/garbage.c    |   13 ++++++++-----
+ 3 files changed, 29 insertions(+), 9 deletions(-)
+
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -830,6 +830,7 @@ struct user_struct {
+       unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
+ #endif
+       unsigned long locked_shm; /* How many pages of mlocked shm ? */
++      unsigned long unix_inflight;    /* How many files in flight in unix sockets */
+ #ifdef CONFIG_KEYS
+       struct key *uid_keyring;        /* UID specific keyring */
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1513,6 +1513,21 @@ static void unix_destruct_scm(struct sk_
+       sock_wfree(skb);
+ }
++/*
++ * The "user->unix_inflight" variable is protected by the garbage
++ * collection lock, and we just read it locklessly here. If you go
++ * over the limit, there might be a tiny race in actually noticing
++ * it across threads. Tough.
++ */
++static inline bool too_many_unix_fds(struct task_struct *p)
++{
++      struct user_struct *user = current_user();
++
++      if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
++              return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
++      return false;
++}
++
+ #define MAX_RECURSION_LEVEL 4
+ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+@@ -1521,6 +1536,9 @@ static int unix_attach_fds(struct scm_co
+       unsigned char max_level = 0;
+       int unix_sock_count = 0;
++      if (too_many_unix_fds(current))
++              return -ETOOMANYREFS;
++
+       for (i = scm->fp->count - 1; i >= 0; i--) {
+               struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+@@ -1542,10 +1560,8 @@ static int unix_attach_fds(struct scm_co
+       if (!UNIXCB(skb).fp)
+               return -ENOMEM;
+-      if (unix_sock_count) {
+-              for (i = scm->fp->count - 1; i >= 0; i--)
+-                      unix_inflight(scm->fp->fp[i]);
+-      }
++      for (i = scm->fp->count - 1; i >= 0; i--)
++              unix_inflight(scm->fp->fp[i]);
+       return max_level;
+ }
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -120,11 +120,11 @@ void unix_inflight(struct file *fp)
+ {
+       struct sock *s = unix_get_socket(fp);
++      spin_lock(&unix_gc_lock);
++
+       if (s) {
+               struct unix_sock *u = unix_sk(s);
+-              spin_lock(&unix_gc_lock);
+-
+               if (atomic_long_inc_return(&u->inflight) == 1) {
+                       BUG_ON(!list_empty(&u->link));
+                       list_add_tail(&u->link, &gc_inflight_list);
+@@ -132,25 +132,28 @@ void unix_inflight(struct file *fp)
+                       BUG_ON(list_empty(&u->link));
+               }
+               unix_tot_inflight++;
+-              spin_unlock(&unix_gc_lock);
+       }
++      fp->f_cred->user->unix_inflight++;
++      spin_unlock(&unix_gc_lock);
+ }
+ void unix_notinflight(struct file *fp)
+ {
+       struct sock *s = unix_get_socket(fp);
++      spin_lock(&unix_gc_lock);
++
+       if (s) {
+               struct unix_sock *u = unix_sk(s);
+-              spin_lock(&unix_gc_lock);
+               BUG_ON(list_empty(&u->link));
+               if (atomic_long_dec_and_test(&u->inflight))
+                       list_del_init(&u->link);
+               unix_tot_inflight--;
+-              spin_unlock(&unix_gc_lock);
+       }
++      fp->f_cred->user->unix_inflight--;
++      spin_unlock(&unix_gc_lock);
+ }
+ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
diff --git a/queue-4.4/vxlan-fix-test-which-detect-duplicate-vxlan-iface.patch b/queue-4.4/vxlan-fix-test-which-detect-duplicate-vxlan-iface.patch
new file mode 100644 (file)
index 0000000..b325aa9
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Tue Jan 26 21:31:27 PST 2016
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Thu, 7 Jan 2016 11:26:53 +0100
+Subject: vxlan: fix test which detect duplicate vxlan iface
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+[ Upstream commit 07b9b37c227cb8d88d478b4a9c5634fee514ede1 ]
+
+When a vxlan interface is created, the driver checks that there is not
+another vxlan interface with the same properties. To do this, it checks
+the existing vxlan udp socket. Since commit 1c51a9159dde, the creation of
+the vxlan socket is done only when the interface is set up, thus it breaks
+that test.
+
+Example:
+$ ip l a vxlan10 type vxlan id 10 group 239.0.0.10 dev eth0 dstport 0
+$ ip l a vxlan11 type vxlan id 10 group 239.0.0.10 dev eth0 dstport 0
+$ ip -br l | grep vxlan
+vxlan10          DOWN           f2:55:1c:6a:fb:00 <BROADCAST,MULTICAST>
+vxlan11          DOWN           7a:cb:b9:38:59:0d <BROADCAST,MULTICAST>
+
+Instead of checking sockets, let's loop over the vxlan iface list.
+
+Fixes: 1c51a9159dde ("vxlan: fix race caused by dropping rtnl_unlock")
+Reported-by: Thomas Faivre <thomas.faivre@6wind.com>
+Signed-off-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>
+---
+ drivers/net/vxlan.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2751,7 +2751,7 @@ static int vxlan_dev_configure(struct ne
+                              struct vxlan_config *conf)
+ {
+       struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
+-      struct vxlan_dev *vxlan = netdev_priv(dev);
++      struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
+       struct vxlan_rdst *dst = &vxlan->default_dst;
+       unsigned short needed_headroom = ETH_HLEN;
+       int err;
+@@ -2817,9 +2817,15 @@ static int vxlan_dev_configure(struct ne
+       if (!vxlan->cfg.age_interval)
+               vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
+-      if (vxlan_find_vni(src_net, conf->vni, use_ipv6 ? AF_INET6 : AF_INET,
+-                         vxlan->cfg.dst_port, vxlan->flags))
++      list_for_each_entry(tmp, &vn->vxlan_list, next) {
++              if (tmp->cfg.vni == conf->vni &&
++                  (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
++                   tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
++                  tmp->cfg.dst_port == vxlan->cfg.dst_port &&
++                  (tmp->flags & VXLAN_F_RCV_FLAGS) ==
++                  (vxlan->flags & VXLAN_F_RCV_FLAGS))
+               return -EEXIST;
++      }
+       dev->ethtool_ops = &vxlan_ethtool_ops;