]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 17:49:43 +0000 (09:49 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 17:49:43 +0000 (09:49 -0800)
added patches:
br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch
inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch
ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch
ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch
macvtap-do-not-double-count-received-packets.patch
macvtap-signal-truncated-packets.patch
macvtap-update-file-current-position.patch
net-clear-local_df-when-passing-skb-between-namespaces.patch
net-do-not-pretend-fraglist-support.patch
net-drop_monitor-fix-the-value-of-maxattr.patch
packet-fix-send-path-when-running-with-proto-0.patch
rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch
tun-unbreak-truncated-packet-signalling.patch
tun-update-file-current-position.patch
virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch

16 files changed:
queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch [new file with mode: 0644]
queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch [new file with mode: 0644]
queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch [new file with mode: 0644]
queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch [new file with mode: 0644]
queue-3.12/macvtap-do-not-double-count-received-packets.patch [new file with mode: 0644]
queue-3.12/macvtap-signal-truncated-packets.patch [new file with mode: 0644]
queue-3.12/macvtap-update-file-current-position.patch [new file with mode: 0644]
queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch [new file with mode: 0644]
queue-3.12/net-do-not-pretend-fraglist-support.patch [new file with mode: 0644]
queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch [new file with mode: 0644]
queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch [new file with mode: 0644]
queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch [new file with mode: 0644]
queue-3.12/series [new file with mode: 0644]
queue-3.12/tun-unbreak-truncated-packet-signalling.patch [new file with mode: 0644]
queue-3.12/tun-update-file-current-position.patch [new file with mode: 0644]
queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch [new file with mode: 0644]

diff --git a/queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch b/queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch
new file mode 100644 (file)
index 0000000..a906c15
--- /dev/null
@@ -0,0 +1,77 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Jiri Pirko <jiri@resnulli.us>
+Date: Thu, 5 Dec 2013 16:27:37 +0100
+Subject: br: fix use of ->rx_handler_data in code executed on non-rx_handler path
+
+From: Jiri Pirko <jiri@resnulli.us>
+
+[ Upstream commit 859828c0ea476b42f3a93d69d117aaba90994b6f ]
+
+br_stp_rcv() is reached by non-rx_handler path. That means there is no
+guarantee that dev is bridge port and therefore simple NULL check of
+->rx_handler_data is not enough. There is need to check if dev is really
+bridge port and since only rcu read lock is held here, do it by checking
+->rx_handler pointer.
+
+Note that synchronize_net() in netdev_rx_handler_unregister() ensures
+this approach as valid.
+
+Introduced originally by:
+commit f350a0a87374418635689471606454abc7beaa3a
+  "bridge: use rx_handler_data pointer to store net_bridge_port pointer"
+
+Fixed but not in the best way by:
+commit b5ed54e94d324f17c97852296d61a143f01b227a
+  "bridge: fix RCU races with bridge port"
+
+Reintroduced by:
+commit 716ec052d2280d511e10e90ad54a86f5b5d4dcc2
+  "bridge: fix NULL pointer deref of br_port_get_rcu"
+
+Please apply to stable trees as well. Thanks.
+
+RH bugzilla reference: https://bugzilla.redhat.com/show_bug.cgi?id=1025770
+
+Reported-by: Laine Stump <laine@redhat.com>
+Debugged-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Jiri Pirko <jiri@resnulli.us>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-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/bridge/br_private.h  |   10 ++++++++++
+ net/bridge/br_stp_bpdu.c |    2 +-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/net/bridge/br_private.h
++++ b/net/bridge/br_private.h
+@@ -442,6 +442,16 @@ extern netdev_features_t br_features_rec
+ extern int br_handle_frame_finish(struct sk_buff *skb);
+ extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
++static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
++{
++      return rcu_dereference(dev->rx_handler) == br_handle_frame;
++}
++
++static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
++{
++      return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
++}
++
+ /* br_ioctl.c */
+ extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);
+--- a/net/bridge/br_stp_bpdu.c
++++ b/net/bridge/br_stp_bpdu.c
+@@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *
+       if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0)
+               goto err;
+-      p = br_port_get_rcu(dev);
++      p = br_port_get_check_rcu(dev);
+       if (!p)
+               goto err;
diff --git a/queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch b/queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch
new file mode 100644 (file)
index 0000000..ef45757
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
+Date: Tue, 10 Dec 2013 23:21:25 +0100
+Subject: inet: fix NULL pointer Oops in fib(6)_rule_suppress
+
+From: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
+
+[ Upstream commit 673498b8ed4c4d4b7221c5309d891c5eac2b7528 ]
+
+This changes ensures that the routing entry investigated by the suppress
+function actually does point to a device struct before following that pointer,
+fixing a possible kernel oops situation when verifying the interface group
+associated with a routing table entry.
+
+According to Daniel Golle, this Oops can be triggered by a user process trying
+to establish an outgoing IPv6 connection while having no real IPv6 connectivity
+set up (only autoassigned link-local addresses).
+
+Fixes: 6ef94cfafba15 ("fib_rules: add route suppression based on ifgroup")
+
+Reported-by: Daniel Golle <daniel.golle@gmail.com>
+Tested-by: Daniel Golle <daniel.golle@gmail.com>
+Signed-off-by: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/fib_rules.c  |    5 ++++-
+ net/ipv6/fib6_rules.c |    6 +++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/fib_rules.c
++++ b/net/ipv4/fib_rules.c
+@@ -104,7 +104,10 @@ errout:
+ static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
+ {
+       struct fib_result *result = (struct fib_result *) arg->result;
+-      struct net_device *dev = result->fi->fib_dev;
++      struct net_device *dev = NULL;
++
++      if (result->fi)
++              dev = result->fi->fib_dev;
+       /* do not accept result if the route does
+        * not meet the required prefix length
+--- a/net/ipv6/fib6_rules.c
++++ b/net/ipv6/fib6_rules.c
+@@ -122,7 +122,11 @@ out:
+ static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
+ {
+       struct rt6_info *rt = (struct rt6_info *) arg->result;
+-      struct net_device *dev = rt->rt6i_idev->dev;
++      struct net_device *dev = NULL;
++
++      if (rt->rt6i_idev)
++              dev = rt->rt6i_idev->dev;
++
+       /* do not accept result if the route does
+        * not meet the required prefix length
+        */
diff --git a/queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch b/queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch
new file mode 100644 (file)
index 0000000..7cc2597
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Sat, 7 Dec 2013 03:33:45 +0100
+Subject: ipv6: don't count addrconf generated routes against gc limit
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit a3300ef4bbb1f1e33ff0400e1e6cf7733d988f4f ]
+
+Brett Ciphery reported that new ipv6 addresses failed to get installed
+because the addrconf generated dsts where counted against the dst gc
+limit. We don't need to count those routes like we currently don't count
+administratively added routes.
+
+Because the max_addresses check enforces a limit on unbounded address
+generation first in case someone plays with router advertisments, we
+are still safe here.
+
+Reported-by: Brett Ciphery <brett.ciphery@windriver.com>
+Signed-off-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/ipv6/route.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2171,12 +2171,10 @@ struct rt6_info *addrconf_dst_alloc(stru
+                                   bool anycast)
+ {
+       struct net *net = dev_net(idev->dev);
+-      struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL);
+-
+-      if (!rt) {
+-              net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n");
++      struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
++                                          DST_NOCOUNT, NULL);
++      if (!rt)
+               return ERR_PTR(-ENOMEM);
+-      }
+       in6_dev_hold(idev);
diff --git a/queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch b/queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch
new file mode 100644 (file)
index 0000000..0d734e4
--- /dev/null
@@ -0,0 +1,97 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Kamala R <kamala@aristanetworks.com>
+Date: Mon, 2 Dec 2013 19:55:21 +0530
+Subject: IPv6: Fixed support for blackhole and prohibit routes
+
+From: Kamala R <kamala@aristanetworks.com>
+
+[ Upstream commit 7150aede5dd241539686e17d9592f5ebd28a2cda ]
+
+The behaviour of blackhole and prohibit routes has been corrected by setting
+the input and output pointers of the dst variable appropriately. For
+blackhole routes, they are set to dst_discard and to ip6_pkt_discard and
+ip6_pkt_discard_out respectively for prohibit routes.
+
+ipv6: ip6_pkt_prohibit(_out) should not depend on
+CONFIG_IPV6_MULTIPLE_TABLES
+
+We need ip6_pkt_prohibit(_out) available without
+CONFIG_IPV6_MULTIPLE_TABLES
+
+Signed-off-by: Kamala R <kamala@aristanetworks.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/ipv6/route.c |   22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -84,6 +84,8 @@ static int            ip6_dst_gc(struct dst_ops *
+ static int            ip6_pkt_discard(struct sk_buff *skb);
+ static int            ip6_pkt_discard_out(struct sk_buff *skb);
++static int            ip6_pkt_prohibit(struct sk_buff *skb);
++static int            ip6_pkt_prohibit_out(struct sk_buff *skb);
+ static void           ip6_link_failure(struct sk_buff *skb);
+ static void           ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
+                                          struct sk_buff *skb, u32 mtu);
+@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_en
+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+-static int ip6_pkt_prohibit(struct sk_buff *skb);
+-static int ip6_pkt_prohibit_out(struct sk_buff *skb);
+-
+ static const struct rt6_info ip6_prohibit_entry_template = {
+       .dst = {
+               .__refcnt       = ATOMIC_INIT(1),
+@@ -1570,21 +1569,24 @@ int ip6_route_add(struct fib6_config *cf
+                               goto out;
+                       }
+               }
+-              rt->dst.output = ip6_pkt_discard_out;
+-              rt->dst.input = ip6_pkt_discard;
+               rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
+               switch (cfg->fc_type) {
+               case RTN_BLACKHOLE:
+                       rt->dst.error = -EINVAL;
++                      rt->dst.output = dst_discard;
++                      rt->dst.input = dst_discard;
+                       break;
+               case RTN_PROHIBIT:
+                       rt->dst.error = -EACCES;
++                      rt->dst.output = ip6_pkt_prohibit_out;
++                      rt->dst.input = ip6_pkt_prohibit;
+                       break;
+               case RTN_THROW:
+-                      rt->dst.error = -EAGAIN;
+-                      break;
+               default:
+-                      rt->dst.error = -ENETUNREACH;
++                      rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
++                                      : -ENETUNREACH;
++                      rt->dst.output = ip6_pkt_discard_out;
++                      rt->dst.input = ip6_pkt_discard;
+                       break;
+               }
+               goto install_route;
+@@ -2149,8 +2151,6 @@ static int ip6_pkt_discard_out(struct sk
+       return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
+ }
+-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+-
+ static int ip6_pkt_prohibit(struct sk_buff *skb)
+ {
+       return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
+@@ -2162,8 +2162,6 @@ static int ip6_pkt_prohibit_out(struct s
+       return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
+ }
+-#endif
+-
+ /*
+  *    Allocate a dst for local (unicast / anycast) address.
+  */
diff --git a/queue-3.12/macvtap-do-not-double-count-received-packets.patch b/queue-3.12/macvtap-do-not-double-count-received-packets.patch
new file mode 100644 (file)
index 0000000..904cfbe
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Vlad Yasevich <vyasevic@redhat.com>
+Date: Tue, 26 Nov 2013 12:37:12 -0500
+Subject: macvtap: Do not double-count received packets
+
+From: Vlad Yasevich <vyasevic@redhat.com>
+
+[ Upstream commit 006da7b07bc4d3a7ffabad17cf639eec6849c9dc ]
+
+Currently macvlan will count received packets after calling each
+vlans receive handler.   Macvtap attempts to count the packet
+yet again when the user reads the packet from the tap socket.
+This code doesn't do this consistently either.  Remove the
+counting from macvtap and let only macvlan count received
+packets.
+
+Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -767,7 +767,6 @@ static ssize_t macvtap_put_user(struct m
+                               const struct sk_buff *skb,
+                               const struct iovec *iv, int len)
+ {
+-      struct macvlan_dev *vlan;
+       int ret;
+       int vnet_hdr_len = 0;
+       int vlan_offset = 0;
+@@ -821,15 +820,6 @@ static ssize_t macvtap_put_user(struct m
+       copied += len;
+ done:
+-      rcu_read_lock();
+-      vlan = rcu_dereference(q->vlan);
+-      if (vlan) {
+-              preempt_disable();
+-              macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
+-              preempt_enable();
+-      }
+-      rcu_read_unlock();
+-
+       return ret ? ret : copied;
+ }
diff --git a/queue-3.12/macvtap-signal-truncated-packets.patch b/queue-3.12/macvtap-signal-truncated-packets.patch
new file mode 100644 (file)
index 0000000..a12a943
--- /dev/null
@@ -0,0 +1,76 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Jason Wang <jasowang@redhat.com>
+Date: Wed, 11 Dec 2013 13:08:34 +0800
+Subject: macvtap: signal truncated packets
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit ce232ce01d61b184202bb185103d119820e1260c ]
+
+macvtap_put_user() never return a value grater than iov length, this in fact
+bypasses the truncated checking in macvtap_recvmsg(). Fix this by always
+returning the size of packet plus the possible vlan header to let the trunca
+checking work.
+
+Cc: Vlad Yasevich <vyasevich@gmail.com>
+Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Vlad Yasevich <vyasevich@gmail.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -770,7 +770,7 @@ static ssize_t macvtap_put_user(struct m
+       int ret;
+       int vnet_hdr_len = 0;
+       int vlan_offset = 0;
+-      int copied;
++      int copied, total;
+       if (q->flags & IFF_VNET_HDR) {
+               struct virtio_net_hdr vnet_hdr;
+@@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct m
+               if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
+                       return -EFAULT;
+       }
+-      copied = vnet_hdr_len;
++      total = copied = vnet_hdr_len;
++      total += skb->len;
+       if (!vlan_tx_tag_present(skb))
+               len = min_t(int, skb->len, len);
+@@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct m
+               vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
+               len = min_t(int, skb->len + VLAN_HLEN, len);
++              total += VLAN_HLEN;
+               copy = min_t(int, vlan_offset, len);
+               ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
+@@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct m
+       }
+       ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+-      copied += len;
+ done:
+-      return ret ? ret : copied;
++      return ret ? ret : total;
+ }
+ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb,
+@@ -875,7 +876,7 @@ static ssize_t macvtap_aio_read(struct k
+       }
+       ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK);
+-      ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */
++      ret = min_t(ssize_t, ret, len);
+       if (ret > 0)
+               iocb->ki_pos = ret;
+ out:
diff --git a/queue-3.12/macvtap-update-file-current-position.patch b/queue-3.12/macvtap-update-file-current-position.patch
new file mode 100644 (file)
index 0000000..b38b393
--- /dev/null
@@ -0,0 +1,27 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Date: Fri, 6 Dec 2013 14:16:50 +0800
+Subject: macvtap: update file current position
+
+From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+
+[ Upstream commit e6ebc7f16ca1434a334647aa56399c546be4e64b ]
+
+Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -886,6 +886,8 @@ static ssize_t macvtap_aio_read(struct k
+       ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK);
+       ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */
++      if (ret > 0)
++              iocb->ki_pos = ret;
+ out:
+       return ret;
+ }
diff --git a/queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch b/queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch
new file mode 100644 (file)
index 0000000..2a2426f
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 5 Dec 2013 23:29:19 +0100
+Subject: net: clear local_df when passing skb between namespaces
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 239c78db9c41a8f524cce60507440d72229d73bc ]
+
+We must clear local_df when passing the skb between namespaces as the
+packet is not local to the new namespace any more and thus may not get
+fragmented by local rules. Fred Templin noticed that other namespaces
+do fragment IPv6 packets while forwarding. Instead they should have send
+back a PTB.
+
+The same problem should be present when forwarding DF-IPv4 packets
+between namespaces.
+
+Reported-by: Templin, Fred L <Fred.L.Templin@boeing.com>
+Signed-off-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/core/skbuff.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3541,6 +3541,7 @@ void skb_scrub_packet(struct sk_buff *sk
+       skb->tstamp.tv64 = 0;
+       skb->pkt_type = PACKET_HOST;
+       skb->skb_iif = 0;
++      skb->local_df = 0;
+       skb_dst_drop(skb);
+       skb->mark = 0;
+       secpath_reset(skb);
diff --git a/queue-3.12/net-do-not-pretend-fraglist-support.patch b/queue-3.12/net-do-not-pretend-fraglist-support.patch
new file mode 100644 (file)
index 0000000..4771ca9
--- /dev/null
@@ -0,0 +1,74 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 2 Dec 2013 08:51:13 -0800
+Subject: net: do not pretend FRAGLIST support
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 28e24c62ab3062e965ef1b3bcc244d50aee7fa85 ]
+
+Few network drivers really supports frag_list : virtual drivers.
+
+Some drivers wrongly advertise NETIF_F_FRAGLIST feature.
+
+If skb with a frag_list is given to them, packet on the wire will be
+corrupt.
+
+Remove this flag, as core networking stack will make sure to
+provide packets that can be sent without corruption.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Cc: Anirudha Sarangi <anirudh@xilinx.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ibm/ehea/ehea_main.c         |    2 +-
+ drivers/net/ethernet/tehuti/tehuti.c              |    1 -
+ drivers/net/ethernet/xilinx/ll_temac_main.c       |    2 +-
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c |    2 +-
+ 4 files changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+@@ -3033,7 +3033,7 @@ static struct ehea_port *ehea_setup_sing
+       dev->hw_features = NETIF_F_SG | NETIF_F_TSO |
+                     NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX;
+-      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO |
++      dev->features = NETIF_F_SG | NETIF_F_TSO |
+                     NETIF_F_HIGHDMA | NETIF_F_IP_CSUM |
+                     NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
+                     NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM;
+--- a/drivers/net/ethernet/tehuti/tehuti.c
++++ b/drivers/net/ethernet/tehuti/tehuti.c
+@@ -2019,7 +2019,6 @@ bdx_probe(struct pci_dev *pdev, const st
+               ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
+                   | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
+                   NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM
+-                  /*| NETIF_F_FRAGLIST */
+                   ;
+               ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+                       NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX;
+--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
+@@ -1016,7 +1016,7 @@ static int temac_of_probe(struct platfor
+       platform_set_drvdata(op, ndev);
+       SET_NETDEV_DEV(ndev, &op->dev);
+       ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
+-      ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
++      ndev->features = NETIF_F_SG;
+       ndev->netdev_ops = &temac_netdev_ops;
+       ndev->ethtool_ops = &temac_ethtool_ops;
+ #if 0
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1486,7 +1486,7 @@ static int axienet_of_probe(struct platf
+       SET_NETDEV_DEV(ndev, &op->dev);
+       ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
+-      ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
++      ndev->features = NETIF_F_SG;
+       ndev->netdev_ops = &axienet_netdev_ops;
+       ndev->ethtool_ops = &axienet_ethtool_ops;
diff --git a/queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch b/queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch
new file mode 100644 (file)
index 0000000..ce94edf
--- /dev/null
@@ -0,0 +1,29 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Changli Gao <xiaosuo@gmail.com>
+Date: Sun, 8 Dec 2013 09:36:56 -0500
+Subject: net: drop_monitor: fix the value of maxattr
+
+From: Changli Gao <xiaosuo@gmail.com>
+
+[ Upstream commit d323e92cc3f4edd943610557c9ea1bb4bb5056e8 ]
+
+maxattr in genl_family should be used to save the max attribute
+type, but not the max command type. Drop monitor doesn't support
+any attributes, so we should leave it as zero.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/drop_monitor.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -64,7 +64,6 @@ static struct genl_family net_drop_monit
+       .hdrsize        = 0,
+       .name           = "NET_DM",
+       .version        = 2,
+-      .maxattr        = NET_DM_CMD_MAX,
+ };
+ static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data);
diff --git a/queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch b/queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch
new file mode 100644 (file)
index 0000000..f1c4c31
--- /dev/null
@@ -0,0 +1,206 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Fri, 6 Dec 2013 11:36:15 +0100
+Subject: packet: fix send path when running with proto == 0
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit 66e56cd46b93ef407c60adcac62cf33b06119d50 ]
+
+Commit e40526cb20b5 introduced a cached dev pointer, that gets
+hooked into register_prot_hook(), __unregister_prot_hook() to
+update the device used for the send path.
+
+We need to fix this up, as otherwise this will not work with
+sockets created with protocol = 0, plus with sll_protocol = 0
+passed via sockaddr_ll when doing the bind.
+
+So instead, assign the pointer directly. The compiler can inline
+these helper functions automagically.
+
+While at it, also assume the cached dev fast-path as likely(),
+and document this variant of socket creation as it seems it is
+not widely used (seems not even the author of TX_RING was aware
+of that in his reference example [1]). Tested with reproducer
+from e40526cb20b5.
+
+ [1] http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap#Example
+
+Fixes: e40526cb20b5 ("packet: fix use after free race in send path when dev is released")
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Tested-by: Salam Noureddine <noureddine@aristanetworks.com>
+Tested-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/networking/packet_mmap.txt |   10 ++++
+ net/packet/af_packet.c                   |   65 +++++++++++++++++++------------
+ 2 files changed, 50 insertions(+), 25 deletions(-)
+
+--- a/Documentation/networking/packet_mmap.txt
++++ b/Documentation/networking/packet_mmap.txt
+@@ -123,6 +123,16 @@ Transmission process is similar to captu
+ [shutdown]  close() --------> destruction of the transmission socket and
+                               deallocation of all associated resources.
++Socket creation and destruction is also straight forward, and is done
++the same way as in capturing described in the previous paragraph:
++
++ int fd = socket(PF_PACKET, mode, 0);
++
++The protocol can optionally be 0 in case we only want to transmit
++via this socket, which avoids an expensive call to packet_rcv().
++In this case, you also need to bind(2) the TX_RING with sll_protocol = 0
++set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example.
++
+ Binding the socket to your network interface is mandatory (with zero copy) to
+ know the header size of frames used in the circular buffer.
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -237,6 +237,30 @@ struct packet_skb_cb {
+ static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
+ static void __fanout_link(struct sock *sk, struct packet_sock *po);
++static struct net_device *packet_cached_dev_get(struct packet_sock *po)
++{
++      struct net_device *dev;
++
++      rcu_read_lock();
++      dev = rcu_dereference(po->cached_dev);
++      if (likely(dev))
++              dev_hold(dev);
++      rcu_read_unlock();
++
++      return dev;
++}
++
++static void packet_cached_dev_assign(struct packet_sock *po,
++                                   struct net_device *dev)
++{
++      rcu_assign_pointer(po->cached_dev, dev);
++}
++
++static void packet_cached_dev_reset(struct packet_sock *po)
++{
++      RCU_INIT_POINTER(po->cached_dev, NULL);
++}
++
+ /* register_prot_hook must be invoked with the po->bind_lock held,
+  * or from a context in which asynchronous accesses to the packet
+  * socket is not possible (packet_create()).
+@@ -246,12 +270,10 @@ static void register_prot_hook(struct so
+       struct packet_sock *po = pkt_sk(sk);
+       if (!po->running) {
+-              if (po->fanout) {
++              if (po->fanout)
+                       __fanout_link(sk, po);
+-              } else {
++              else
+                       dev_add_pack(&po->prot_hook);
+-                      rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
+-              }
+               sock_hold(sk);
+               po->running = 1;
+@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struc
+       struct packet_sock *po = pkt_sk(sk);
+       po->running = 0;
+-      if (po->fanout) {
++
++      if (po->fanout)
+               __fanout_unlink(sk, po);
+-      } else {
++      else
+               __dev_remove_pack(&po->prot_hook);
+-              RCU_INIT_POINTER(po->cached_dev, NULL);
+-      }
+       __sock_put(sk);
+@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packe
+       return tp_len;
+ }
+-static struct net_device *packet_cached_dev_get(struct packet_sock *po)
+-{
+-      struct net_device *dev;
+-
+-      rcu_read_lock();
+-      dev = rcu_dereference(po->cached_dev);
+-      if (dev)
+-              dev_hold(dev);
+-      rcu_read_unlock();
+-
+-      return dev;
+-}
+-
+ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ {
+       struct sk_buff *skb;
+@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_soc
+       mutex_lock(&po->pg_vec_lock);
+-      if (saddr == NULL) {
++      if (likely(saddr == NULL)) {
+               dev     = packet_cached_dev_get(po);
+               proto   = po->num;
+               addr    = NULL;
+@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *soc
+        *      Get and verify the address.
+        */
+-      if (saddr == NULL) {
++      if (likely(saddr == NULL)) {
+               dev     = packet_cached_dev_get(po);
+               proto   = po->num;
+               addr    = NULL;
+@@ -2451,6 +2459,8 @@ static int packet_release(struct socket
+       spin_lock(&po->bind_lock);
+       unregister_prot_hook(sk, false);
++      packet_cached_dev_reset(po);
++
+       if (po->prot_hook.dev) {
+               dev_put(po->prot_hook.dev);
+               po->prot_hook.dev = NULL;
+@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *s
+       spin_lock(&po->bind_lock);
+       unregister_prot_hook(sk, true);
++
+       po->num = protocol;
+       po->prot_hook.type = protocol;
+       if (po->prot_hook.dev)
+               dev_put(po->prot_hook.dev);
+-      po->prot_hook.dev = dev;
++      po->prot_hook.dev = dev;
+       po->ifindex = dev ? dev->ifindex : 0;
++      packet_cached_dev_assign(po, dev);
++
+       if (protocol == 0)
+               goto out_unlock;
+@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net
+       po = pkt_sk(sk);
+       sk->sk_family = PF_PACKET;
+       po->num = proto;
+-      RCU_INIT_POINTER(po->cached_dev, NULL);
++
++      packet_cached_dev_reset(po);
+       sk->sk_destruct = packet_sock_destruct;
+       sk_refcnt_debug_inc(sk);
+@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifi
+                                               sk->sk_error_report(sk);
+                               }
+                               if (msg == NETDEV_UNREGISTER) {
++                                      packet_cached_dev_reset(po);
+                                       po->ifindex = -1;
+                                       if (po->prot_hook.dev)
+                                               dev_put(po->prot_hook.dev);
diff --git a/queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch b/queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch
new file mode 100644 (file)
index 0000000..85919d4
--- /dev/null
@@ -0,0 +1,90 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
+Date: Mon, 2 Dec 2013 15:41:39 -0800
+Subject: rds: prevent BUG_ON triggered on congestion update to loopback
+
+From: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
+
+[ Upstream commit 18fc25c94eadc52a42c025125af24657a93638c0 ]
+
+After congestion update on a local connection, when rds_ib_xmit returns
+less bytes than that are there in the message, rds_send_xmit calls
+back rds_ib_xmit with an offset that causes BUG_ON(off & RDS_FRAG_SIZE)
+to trigger.
+
+For a 4Kb PAGE_SIZE rds_ib_xmit returns min(8240,4096)=4096 when actually
+the message contains 8240 bytes. rds_send_xmit thinks there is more to send
+and calls rds_ib_xmit again with a data offset "off" of 4096-48(rds header)
+=4048 bytes thus hitting the BUG_ON(off & RDS_FRAG_SIZE) [RDS_FRAG_SIZE=4k].
+
+The commit 6094628bfd94323fc1cea05ec2c6affd98c18f7f
+"rds: prevent BUG_ON triggering on congestion map updates" introduced
+this regression. That change was addressing the triggering of a different
+BUG_ON in rds_send_xmit() on PowerPC architecture with 64Kbytes PAGE_SIZE:
+       BUG_ON(ret != 0 &&
+                conn->c_xmit_sg == rm->data.op_nents);
+This was the sequence it was going through:
+(rds_ib_xmit)
+/* Do not send cong updates to IB loopback */
+if (conn->c_loopback
+   && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
+       rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
+       return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
+}
+rds_ib_xmit returns 8240
+rds_send_xmit:
+  c_xmit_data_off = 0 + 8240 - 48 (rds header accounted only the first time)
+                = 8192
+  c_xmit_data_off < 65536 (sg->length), so calls rds_ib_xmit again
+rds_ib_xmit returns 8240
+rds_send_xmit:
+  c_xmit_data_off = 8192 + 8240 = 16432, calls rds_ib_xmit again
+  and so on (c_xmit_data_off 24672,32912,41152,49392,57632)
+rds_ib_xmit returns 8240
+On this iteration this sequence causes the BUG_ON in rds_send_xmit:
+    while (ret) {
+       tmp = min_t(int, ret, sg->length - conn->c_xmit_data_off);
+       [tmp = 65536 - 57632 = 7904]
+       conn->c_xmit_data_off += tmp;
+       [c_xmit_data_off = 57632 + 7904 = 65536]
+       ret -= tmp;
+       [ret = 8240 - 7904 = 336]
+       if (conn->c_xmit_data_off == sg->length) {
+               conn->c_xmit_data_off = 0;
+               sg++;
+               conn->c_xmit_sg++;
+               BUG_ON(ret != 0 &&
+                       conn->c_xmit_sg == rm->data.op_nents);
+               [c_xmit_sg = 1, rm->data.op_nents = 1]
+
+What the current fix does:
+Since the congestion update over loopback is not actually transmitted
+as a message, all that rds_ib_xmit needs to do is let the caller think
+the full message has been transmitted and not return partial bytes.
+It will return 8240 (RDS_CONG_MAP_BYTES+48) when PAGE_SIZE is 4Kb.
+And 64Kb+48 when page size is 64Kb.
+
+Reported-by: Josh Hunt <joshhunt00@gmail.com>
+Tested-by: Honggang Li <honli@redhat.com>
+Acked-by: Bang Nguyen <bang.nguyen@oracle.com>
+Signed-off-by: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rds/ib_send.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *c
+           && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
+               rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
+               scat = &rm->data.op_sg[sg];
+-              ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
+-              ret = min_t(int, ret, scat->length - conn->c_xmit_data_off);
+-              return ret;
++              ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length);
++              return sizeof(struct rds_header) + ret;
+       }
+       /* FIXME we may overallocate here */
diff --git a/queue-3.12/series b/queue-3.12/series
new file mode 100644 (file)
index 0000000..a06652a
--- /dev/null
@@ -0,0 +1,15 @@
+ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch
+net-do-not-pretend-fraglist-support.patch
+rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch
+net-clear-local_df-when-passing-skb-between-namespaces.patch
+macvtap-update-file-current-position.patch
+tun-update-file-current-position.patch
+tun-unbreak-truncated-packet-signalling.patch
+macvtap-do-not-double-count-received-packets.patch
+macvtap-signal-truncated-packets.patch
+virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch
+br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch
+packet-fix-send-path-when-running-with-proto-0.patch
+ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch
+net-drop_monitor-fix-the-value-of-maxattr.patch
+inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch
diff --git a/queue-3.12/tun-unbreak-truncated-packet-signalling.patch b/queue-3.12/tun-unbreak-truncated-packet-signalling.patch
new file mode 100644 (file)
index 0000000..79f1338
--- /dev/null
@@ -0,0 +1,78 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Jason Wang <jasowang@redhat.com>
+Date: Wed, 11 Dec 2013 13:08:33 +0800
+Subject: tun: unbreak truncated packet signalling
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit e6fd07c899cd719bb5517bc7f32ce03a62220351 ]
+
+Commit 6680ec68eff47d36f67b4351bc9836fd6cba9532
+(tuntap: hardware vlan tx support) breaks the truncated packet signal by nev
+return a length greater than iov length in tun_put_user(). This patch fixes
+by always return the length of packet plus possible vlan header. Caller can
+detect the truncated packet by comparing the return value and the size of io
+length.
+
+Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1184,7 +1184,7 @@ static ssize_t tun_put_user(struct tun_s
+ {
+       struct tun_pi pi = { 0, skb->protocol };
+       ssize_t total = 0;
+-      int vlan_offset = 0;
++      int vlan_offset = 0, copied;
+       if (!(tun->flags & TUN_NO_PI)) {
+               if ((len -= sizeof(pi)) < 0)
+@@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_s
+               total += tun->vnet_hdr_sz;
+       }
++      copied = total;
++      total += skb->len;
+       if (!vlan_tx_tag_present(skb)) {
+               len = min_t(int, skb->len, len);
+       } else {
+@@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_s
+               vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
+               len = min_t(int, skb->len + VLAN_HLEN, len);
++              total += VLAN_HLEN;
+               copy = min_t(int, vlan_offset, len);
+-              ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy);
++              ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
+               len -= copy;
+-              total += copy;
++              copied += copy;
+               if (ret || !len)
+                       goto done;
+               copy = min_t(int, sizeof(veth), len);
+-              ret = memcpy_toiovecend(iv, (void *)&veth, total, copy);
++              ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
+               len -= copy;
+-              total += copy;
++              copied += copy;
+               if (ret || !len)
+                       goto done;
+       }
+-      skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len);
+-      total += len;
++      skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+ done:
+       tun->dev->stats.tx_packets++;
diff --git a/queue-3.12/tun-update-file-current-position.patch b/queue-3.12/tun-update-file-current-position.patch
new file mode 100644 (file)
index 0000000..6547c3e
--- /dev/null
@@ -0,0 +1,27 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Date: Fri, 6 Dec 2013 14:16:51 +0800
+Subject: tun: update file current position
+
+From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+
+[ Upstream commit d0b7da8afa079ffe018ab3e92879b7138977fc8f ]
+
+Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1356,6 +1356,8 @@ static ssize_t tun_chr_aio_read(struct k
+       ret = tun_do_read(tun, tfile, iocb, iv, len,
+                         file->f_flags & O_NONBLOCK);
+       ret = min_t(ssize_t, ret, len);
++      if (ret > 0)
++              iocb->ki_pos = ret;
+ out:
+       tun_put(tun);
+       return ret;
diff --git a/queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch b/queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch
new file mode 100644 (file)
index 0000000..5541835
--- /dev/null
@@ -0,0 +1,80 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Andrey Vagin <avagin@openvz.org>
+Date: Thu, 5 Dec 2013 18:36:21 +0400
+Subject: virtio: delete napi structures from netdev before releasing memory
+
+From: Andrey Vagin <avagin@openvz.org>
+
+[ Upstream commit d4fb84eefe5164f6a6ea51d0a9e26280c661a0dd ]
+
+free_netdev calls netif_napi_del too, but it's too late, because napi
+structures are placed on vi->rq. netif_napi_add() is called from
+virtnet_alloc_queues.
+
+general protection fault: 0000 [#1] SMP
+Dumping ftrace buffer:
+   (ftrace buffer empty)
+Modules linked in: ip6table_filter ip6_tables iptable_filter ip_tables virtio_balloon pcspkr virtio_net(-) i2c_pii
+CPU: 1 PID: 347 Comm: rmmod Not tainted 3.13.0-rc2+ #171
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+task: ffff8800b779c420 ti: ffff8800379e0000 task.ti: ffff8800379e0000
+RIP: 0010:[<ffffffff81322e19>]  [<ffffffff81322e19>] __list_del_entry+0x29/0xd0
+RSP: 0018:ffff8800379e1dd0  EFLAGS: 00010a83
+RAX: 6b6b6b6b6b6b6b6b RBX: ffff8800379c2fd0 RCX: dead000000200200
+RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000001 RDI: ffff8800379c2fd0
+RBP: ffff8800379e1dd0 R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000001 R12: ffff8800379c2f90
+R13: ffff880037839160 R14: 0000000000000000 R15: 00000000013352f0
+FS:  00007f1400e34740(0000) GS:ffff8800bfb00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+CR2: 00007f464124c763 CR3: 00000000b68cf000 CR4: 00000000000006e0
+Stack:
+ ffff8800379e1df0 ffffffff8155beab 6b6b6b6b6b6b6b2b ffff8800378391c0
+ ffff8800379e1e18 ffffffff8156499b ffff880037839be0 ffff880037839d20
+ ffff88003779d3f0 ffff8800379e1e38 ffffffffa003477c ffff88003779d388
+Call Trace:
+ [<ffffffff8155beab>] netif_napi_del+0x1b/0x80
+ [<ffffffff8156499b>] free_netdev+0x8b/0x110
+ [<ffffffffa003477c>] virtnet_remove+0x7c/0x90 [virtio_net]
+ [<ffffffff813ae323>] virtio_dev_remove+0x23/0x80
+ [<ffffffff813f62ef>] __device_release_driver+0x7f/0xf0
+ [<ffffffff813f6ca0>] driver_detach+0xc0/0xd0
+ [<ffffffff813f5f28>] bus_remove_driver+0x58/0xd0
+ [<ffffffff813f72ec>] driver_unregister+0x2c/0x50
+ [<ffffffff813ae65e>] unregister_virtio_driver+0xe/0x10
+ [<ffffffffa0036942>] virtio_net_driver_exit+0x10/0x6ce [virtio_net]
+ [<ffffffff810d7cf2>] SyS_delete_module+0x172/0x220
+ [<ffffffff810a732d>] ? trace_hardirqs_on+0xd/0x10
+ [<ffffffff810f5d4c>] ? __audit_syscall_entry+0x9c/0xf0
+ [<ffffffff81677f69>] system_call_fastpath+0x16/0x1b
+Code: 00 00 55 48 8b 17 48 b9 00 01 10 00 00 00 ad de 48 8b 47 08 48 89 e5 48 39 ca 74 29 48 b9 00 02 20 00 00 00
+RIP  [<ffffffff81322e19>] __list_del_entry+0x29/0xd0
+ RSP <ffff8800379e1dd0>
+---[ end trace d5931cd3f87c9763 ]---
+
+Fixes: 986a4f4d452d (virtio_net: multiqueue support)
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Signed-off-by: Andrey Vagin <avagin@openvz.org>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1307,6 +1307,11 @@ static void virtnet_config_changed(struc
+ static void virtnet_free_queues(struct virtnet_info *vi)
+ {
++      int i;
++
++      for (i = 0; i < vi->max_queue_pairs; i++)
++              netif_napi_del(&vi->rq[i].napi);
++
+       kfree(vi->rq);
+       kfree(vi->sq);
+ }