]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2013 21:56:58 +0000 (17:56 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2013 21:56:58 +0000 (17:56 -0400)
added patches:
3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
3c59x-fix-pci-resource-management.patch
asix-fix-bug-in-receive-path-when-lowering-mtu.patch
bridge-fix-race-with-topology-change-timer.patch
if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
ipv6-do-not-clear-pinet6-field.patch
ipv6-gre-do-not-leak-info-to-user-space.patch
macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
net-frag-fix-race-conditions-in-lru-list-maintenance.patch
net-mac802154-comparision-issue-of-type-cast-finding-by-extra_cflags-w.patch
net_sched-act_ipt-forward-compat-with-xtables.patch
net-tun-release-the-reference-of-tun-device-in-tun_recvmsg.patch
net-use-netdev_features_t-in-skb_needs_linearize.patch
net-vlan-ethtool-netdev_features_t-is-more-than-32-bit.patch
packet-tpacket_v3-do-not-trigger-bug-on-wrong-header-status.patch
sfc-fix-naming-of-mtd-partitions-for-fpga-bitfiles.patch
tcp-force-a-dst-refcount-when-prequeue-packet.patch
tcp-reset-timer-after-any-synack-retransmit.patch
virtio-don-t-expose-u16-in-userspace-api.patch
xfrm6-release-dev-before-returning-error.patch

22 files changed:
queue-3.9/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch [new file with mode: 0644]
queue-3.9/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch [new file with mode: 0644]
queue-3.9/3c59x-fix-pci-resource-management.patch [new file with mode: 0644]
queue-3.9/asix-fix-bug-in-receive-path-when-lowering-mtu.patch [new file with mode: 0644]
queue-3.9/bridge-fix-race-with-topology-change-timer.patch [new file with mode: 0644]
queue-3.9/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch [new file with mode: 0644]
queue-3.9/ipv6-do-not-clear-pinet6-field.patch [new file with mode: 0644]
queue-3.9/ipv6-gre-do-not-leak-info-to-user-space.patch [new file with mode: 0644]
queue-3.9/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch [new file with mode: 0644]
queue-3.9/net-frag-fix-race-conditions-in-lru-list-maintenance.patch [new file with mode: 0644]
queue-3.9/net-mac802154-comparision-issue-of-type-cast-finding-by-extra_cflags-w.patch [new file with mode: 0644]
queue-3.9/net-tun-release-the-reference-of-tun-device-in-tun_recvmsg.patch [new file with mode: 0644]
queue-3.9/net-use-netdev_features_t-in-skb_needs_linearize.patch [new file with mode: 0644]
queue-3.9/net-vlan-ethtool-netdev_features_t-is-more-than-32-bit.patch [new file with mode: 0644]
queue-3.9/net_sched-act_ipt-forward-compat-with-xtables.patch [new file with mode: 0644]
queue-3.9/packet-tpacket_v3-do-not-trigger-bug-on-wrong-header-status.patch [new file with mode: 0644]
queue-3.9/series
queue-3.9/sfc-fix-naming-of-mtd-partitions-for-fpga-bitfiles.patch [new file with mode: 0644]
queue-3.9/tcp-force-a-dst-refcount-when-prequeue-packet.patch [new file with mode: 0644]
queue-3.9/tcp-reset-timer-after-any-synack-retransmit.patch [new file with mode: 0644]
queue-3.9/virtio-don-t-expose-u16-in-userspace-api.patch [new file with mode: 0644]
queue-3.9/xfrm6-release-dev-before-returning-error.patch [new file with mode: 0644]

diff --git a/queue-3.9/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch b/queue-3.9/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
new file mode 100644 (file)
index 0000000..63a01f3
--- /dev/null
@@ -0,0 +1,49 @@
+From f80adb4f6d1d526049b6bc222f4e1966990844de Mon Sep 17 00:00:00 2001
+From: Matthew Whitehead <tedheadster@gmail.com>
+Date: Mon, 29 Apr 2013 17:46:53 -0400
+Subject: 3c509.c: call SET_NETDEV_DEV for all device types (ISA/ISAPnP/EISA)
+
+
+From: Matthew Whitehead <tedheadster@gmail.com>
+
+[ Upstream commit 3b54912f9cd167641b91d4a697bd742f70e534fe ]
+
+The venerable 3c509 driver only sets its device parent in one case, the ISAPnP one.
+It does this with the SET_NETDEV_DEV function. It should register with the device
+hierarchy in two additional cases: standard (non-PnP) ISA and EISA.
+
+- Currently they appear here:
+/sys/devices/virtual/net/eth0 (standard ISA)
+/sys/devices/virtual/net/eth1 (EISA)
+
+- Rather, they should instead be here:
+/sys/devices/isa/3c509.0/net/eth0 (standard ISA)
+/sys/devices/pci0000:00/0000:00:07.0/00:04/net/eth1 (EISA)
+
+Tested on ISA and EISA boards.
+
+Signed-off-by: Matthew Whitehead <tedheadster@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/3com/3c509.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/3com/3c509.c
++++ b/drivers/net/ethernet/3com/3c509.c
+@@ -306,6 +306,7 @@ static int el3_isa_match(struct device *
+       if (!dev)
+               return -ENOMEM;
++      SET_NETDEV_DEV(dev, pdev);
+       netdev_boot_setup_check(dev);
+       if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
+@@ -595,6 +596,7 @@ static int __init el3_eisa_probe (struct
+               return -ENOMEM;
+       }
++      SET_NETDEV_DEV(dev, device);
+       netdev_boot_setup_check(dev);
+       el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
diff --git a/queue-3.9/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch b/queue-3.9/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
new file mode 100644 (file)
index 0000000..046f458
--- /dev/null
@@ -0,0 +1,40 @@
+From 6cf5effb640547819fc46e2d71c8e0843172fd25 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 2 May 2013 11:10:22 +0000
+Subject: 3c59x: fix freeing nonexistent resource on driver unload
+
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+[ Upstream commit c81400be716aa4c76f6ebf339ba94358dbbf6da6 ]
+
+When unloading the driver that drives an EISA board, a message similar to the
+following one is displayed:
+
+Trying to free nonexistent resource <0000000000013000-000000000001301f>
+
+Then an user is unable to reload the driver because the resource it requested in
+the previous load hasn't been freed. This happens most probably due to a typo in
+vortex_eisa_remove() which calls release_region() with 'dev->base_addr'  instead
+of 'edev->base_addr'...
+
+Reported-by: Matthew Whitehead <tedheadster@gmail.com>
+Tested-by: Matthew Whitehead <tedheadster@gmail.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/3com/3c59x.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/3com/3c59x.c
++++ b/drivers/net/ethernet/3com/3c59x.c
+@@ -951,7 +951,7 @@ static int vortex_eisa_remove(struct dev
+       unregister_netdev(dev);
+       iowrite16(TotalReset|0x14, ioaddr + EL3_CMD);
+-      release_region(dev->base_addr, VORTEX_TOTAL_SIZE);
++      release_region(edev->base_addr, VORTEX_TOTAL_SIZE);
+       free_netdev(dev);
+       return 0;
diff --git a/queue-3.9/3c59x-fix-pci-resource-management.patch b/queue-3.9/3c59x-fix-pci-resource-management.patch
new file mode 100644 (file)
index 0000000..621ab8b
--- /dev/null
@@ -0,0 +1,105 @@
+From 6cc1c21b4665144d8641e7b819ae1055a7ac6bba Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Thu, 9 May 2013 11:14:07 +0000
+Subject: 3c59x: fix PCI resource management
+
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+[ Upstream commit 4b264a1676e70dc656ba53a8cac690f2d4b65f4e ]
+
+The driver wrongly claimed I/O ports at an address returned by pci_iomap() --
+even if it was passed an MMIO address.  Fix this by claiming/releasing all PCI
+resources in the PCI driver's probe()/remove() methods instead and get rid of
+'must_free_region' flag weirdness (why would Cardbus claim anything for us?).
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/3com/3c59x.c |   25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/ethernet/3com/3c59x.c
++++ b/drivers/net/ethernet/3com/3c59x.c
+@@ -632,7 +632,6 @@ struct vortex_private {
+               pm_state_valid:1,                               /* pci_dev->saved_config_space has sane contents */
+               open:1,
+               medialock:1,
+-              must_free_region:1,                             /* Flag: if zero, Cardbus owns the I/O region */
+               large_frames:1,                 /* accept large frames */
+               handling_irq:1;                 /* private in_irq indicator */
+       /* {get|set}_wol operations are already serialized by rtnl.
+@@ -1012,6 +1011,12 @@ static int vortex_init_one(struct pci_de
+       if (rc < 0)
+               goto out;
++      rc = pci_request_regions(pdev, DRV_NAME);
++      if (rc < 0) {
++              pci_disable_device(pdev);
++              goto out;
++      }
++
+       unit = vortex_cards_found;
+       if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+@@ -1027,6 +1032,7 @@ static int vortex_init_one(struct pci_de
+       if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+               ioaddr = pci_iomap(pdev, 0, 0);
+       if (!ioaddr) {
++              pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               rc = -ENOMEM;
+               goto out;
+@@ -1036,6 +1042,7 @@ static int vortex_init_one(struct pci_de
+                          ent->driver_data, unit);
+       if (rc < 0) {
+               pci_iounmap(pdev, ioaddr);
++              pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               goto out;
+       }
+@@ -1178,11 +1185,6 @@ static int vortex_probe1(struct device *
+       /* PCI-only startup logic */
+       if (pdev) {
+-              /* EISA resources already marked, so only PCI needs to do this here */
+-              /* Ignore return value, because Cardbus drivers already allocate for us */
+-              if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
+-                      vp->must_free_region = 1;
+-
+               /* enable bus-mastering if necessary */
+               if (vci->flags & PCI_USES_MASTER)
+                       pci_set_master(pdev);
+@@ -1220,7 +1222,7 @@ static int vortex_probe1(struct device *
+                                          &vp->rx_ring_dma);
+       retval = -ENOMEM;
+       if (!vp->rx_ring)
+-              goto free_region;
++              goto free_device;
+       vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
+       vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
+@@ -1484,9 +1486,7 @@ free_ring:
+                                                       + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
+                                               vp->rx_ring,
+                                               vp->rx_ring_dma);
+-free_region:
+-      if (vp->must_free_region)
+-              release_region(dev->base_addr, vci->io_size);
++free_device:
+       free_netdev(dev);
+       pr_err(PFX "vortex_probe1 fails.  Returns %d\n", retval);
+ out:
+@@ -3254,8 +3254,9 @@ static void vortex_remove_one(struct pci
+                                                       + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
+                                               vp->rx_ring,
+                                               vp->rx_ring_dma);
+-      if (vp->must_free_region)
+-              release_region(dev->base_addr, vp->io_size);
++
++      pci_release_regions(pdev);
++
+       free_netdev(dev);
+ }
diff --git a/queue-3.9/asix-fix-bug-in-receive-path-when-lowering-mtu.patch b/queue-3.9/asix-fix-bug-in-receive-path-when-lowering-mtu.patch
new file mode 100644 (file)
index 0000000..33f9f89
--- /dev/null
@@ -0,0 +1,58 @@
+From a5e431f5e7c0b56c68774e080f97aa8841c9478e Mon Sep 17 00:00:00 2001
+From: "holger@eitzenberger.org" <holger@eitzenberger.org>
+Date: Fri, 3 May 2013 00:02:20 +0000
+Subject: asix: fix BUG in receive path when lowering MTU
+
+
+From: "holger@eitzenberger.org" <holger@eitzenberger.org>
+
+[ Upstream commit c5060cec6ba27ad3f0e7facfdf05d2f18e3e3010 ]
+
+There is bug in the receive path of the asix driver at the time a
+packet is received larger than MTU size and DF bit set:
+
+ BUG: unable to handle kernel paging request at 0000004000000001
+ IP: [<ffffffff8126f65b>] skb_release_head_state+0x2d/0xd2
+ ...
+ Call Trace:
+  <IRQ>
+  [<ffffffff8126f86d>] ? skb_release_all+0x9/0x1e
+  [<ffffffff8126f8ad>] ? __kfree_skb+0x9/0x6f
+  [<ffffffffa00b4200>] ? asix_rx_fixup_internal+0xff/0x1ae [asix]
+  [<ffffffffa00fb3dc>] ? usbnet_bh+0x4f/0x226 [usbnet]
+  ...
+
+It is easily reproducable by setting an MTU of 512 e. g. and sending
+something like
+
+  ping -s 1472 -c 1 -M do $SELF
+
+from another box.
+
+And this is because the rx->ax_skb is freed on error, but rx->ax_skb
+is not reset, and the size is not reset to zero in this case.
+
+And since the skb is added again to the usbnet->done skb queue it is
+accessing already freed memory, resulting in the BUG when freeing a
+2nd time.  I therefore think the value 0x0000004000000001 show in the
+trace is more or less random data.
+
+Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/asix_common.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/usb/asix_common.c
++++ b/drivers/net/usb/asix_common.c
+@@ -100,6 +100,9 @@ int asix_rx_fixup_internal(struct usbnet
+                       netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
+                                  rx->size);
+                       kfree_skb(rx->ax_skb);
++                      rx->ax_skb = NULL;
++                      rx->size = 0U;
++
+                       return 0;
+               }
diff --git a/queue-3.9/bridge-fix-race-with-topology-change-timer.patch b/queue-3.9/bridge-fix-race-with-topology-change-timer.patch
new file mode 100644 (file)
index 0000000..1eb1bbf
--- /dev/null
@@ -0,0 +1,37 @@
+From b8158b936bde6be3ff59a8261252f1003cb72020 Mon Sep 17 00:00:00 2001
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Thu, 2 May 2013 14:23:28 +0000
+Subject: bridge: fix race with topology change timer
+
+
+From: stephen hemminger <stephen@networkplumber.org>
+
+[ Upstream commit 83401eb4990ff6af55aeed8f49681558544192e6 ]
+
+A bridge should only send topology change notice if it is not
+the root bridge. It is possible for message age timer to elect itself
+as a new root bridge, and still have a topology change timer running
+but waiting for bridge lock on other CPU.
+
+Solve the race by checking if we are root bridge before continuing.
+This was the root cause of the cases where br_send_tcn_bpdu would OOPS.
+
+Reported-by: JerryKang <jerry.kang@samsung.com>
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_stp_timer.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bridge/br_stp_timer.c
++++ b/net/bridge/br_stp_timer.c
+@@ -107,7 +107,7 @@ static void br_tcn_timer_expired(unsigne
+       br_debug(br, "tcn timer expired\n");
+       spin_lock(&br->lock);
+-      if (br->dev->flags & IFF_UP) {
++      if (!br_is_root_bridge(br) && (br->dev->flags & IFF_UP)) {
+               br_transmit_tcn(br);
+               mod_timer(&br->tcn_timer,jiffies + br->bridge_hello_time);
diff --git a/queue-3.9/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch b/queue-3.9/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
new file mode 100644 (file)
index 0000000..4f5d952
--- /dev/null
@@ -0,0 +1,40 @@
+From 816b268677ffe2cfcc296eac1b814c745eef5deb Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Wed, 8 May 2013 09:45:47 +0000
+Subject: if_cablemodem.h: Add parenthesis around ioctl macros
+
+
+From: Josh Boyer <jwboyer@redhat.com>
+
+[ Upstream commit 4f924b2aa4d3cb30f07e57d6b608838edcbc0d88 ]
+
+Protect the SIOCGCM* ioctl macros with parenthesis.
+
+Reported-by: Paul Wouters <pwouters@redhat.com>
+Signed-off-by: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/uapi/linux/if_cablemodem.h |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/include/uapi/linux/if_cablemodem.h
++++ b/include/uapi/linux/if_cablemodem.h
+@@ -12,11 +12,11 @@
+  */
+ /* some useful defines for sb1000.c e cmconfig.c - fv */
+-#define SIOCGCMSTATS          SIOCDEVPRIVATE+0        /* get cable modem stats */
+-#define SIOCGCMFIRMWARE               SIOCDEVPRIVATE+1        /* get cm firmware version */
+-#define SIOCGCMFREQUENCY      SIOCDEVPRIVATE+2        /* get cable modem frequency */
+-#define SIOCSCMFREQUENCY      SIOCDEVPRIVATE+3        /* set cable modem frequency */
+-#define SIOCGCMPIDS                   SIOCDEVPRIVATE+4        /* get cable modem PIDs */
+-#define SIOCSCMPIDS                   SIOCDEVPRIVATE+5        /* set cable modem PIDs */
++#define SIOCGCMSTATS          (SIOCDEVPRIVATE+0)      /* get cable modem stats */
++#define SIOCGCMFIRMWARE               (SIOCDEVPRIVATE+1)      /* get cm firmware version */
++#define SIOCGCMFREQUENCY      (SIOCDEVPRIVATE+2)      /* get cable modem frequency */
++#define SIOCSCMFREQUENCY      (SIOCDEVPRIVATE+3)      /* set cable modem frequency */
++#define SIOCGCMPIDS                   (SIOCDEVPRIVATE+4)      /* get cable modem PIDs */
++#define SIOCSCMPIDS                   (SIOCDEVPRIVATE+5)      /* set cable modem PIDs */
+ #endif
diff --git a/queue-3.9/ipv6-do-not-clear-pinet6-field.patch b/queue-3.9/ipv6-do-not-clear-pinet6-field.patch
new file mode 100644 (file)
index 0000000..eaec309
--- /dev/null
@@ -0,0 +1,163 @@
+From 2c34eb3ee8c4cd204d7360657b3d948de1d5aab8 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 9 May 2013 10:28:16 +0000
+Subject: ipv6: do not clear pinet6 field
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f77d602124d865c38705df7fa25c03de9c284ad2 ]
+
+We have seen multiple NULL dereferences in __inet6_lookup_established()
+
+After analysis, I found that inet6_sk() could be NULL while the
+check for sk_family == AF_INET6 was true.
+
+Bug was added in linux-2.6.29 when RCU lookups were introduced in UDP
+and TCP stacks.
+
+Once an IPv6 socket, using SLAB_DESTROY_BY_RCU is inserted in a hash
+table, we no longer can clear pinet6 field.
+
+This patch extends logic used in commit fcbdf09d9652c891
+("net: fix nulls list corruptions in sk_prot_alloc")
+
+TCP/UDP/UDPLite IPv6 protocols provide their own .clear_sk() method
+to make sure we do not clear pinet6 field.
+
+At socket clone phase, we do not really care, as cloning the parent (non
+NULL) pinet6 is not adding a fatal race.
+
+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>
+---
+ include/net/sock.h  |   12 ++++++++++++
+ net/core/sock.c     |   12 ------------
+ net/ipv6/tcp_ipv6.c |   12 ++++++++++++
+ net/ipv6/udp.c      |   13 ++++++++++++-
+ net/ipv6/udp_impl.h |    2 ++
+ net/ipv6/udplite.c  |    2 +-
+ 6 files changed, 39 insertions(+), 14 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -865,6 +865,18 @@ struct inet_hashinfo;
+ struct raw_hashinfo;
+ struct module;
++/*
++ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
++ * un-modified. Special care is taken when initializing object to zero.
++ */
++static inline void sk_prot_clear_nulls(struct sock *sk, int size)
++{
++      if (offsetof(struct sock, sk_node.next) != 0)
++              memset(sk, 0, offsetof(struct sock, sk_node.next));
++      memset(&sk->sk_node.pprev, 0,
++             size - offsetof(struct sock, sk_node.pprev));
++}
++
+ /* Networking protocol blocks we attach to sockets.
+  * socket layer -> transport layer interface
+  * transport -> network interface is defined by struct inet_proto
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1209,18 +1209,6 @@ static void sock_copy(struct sock *nsk,
+ #endif
+ }
+-/*
+- * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
+- * un-modified. Special care is taken when initializing object to zero.
+- */
+-static inline void sk_prot_clear_nulls(struct sock *sk, int size)
+-{
+-      if (offsetof(struct sock, sk_node.next) != 0)
+-              memset(sk, 0, offsetof(struct sock, sk_node.next));
+-      memset(&sk->sk_node.pprev, 0,
+-             size - offsetof(struct sock, sk_node.pprev));
+-}
+-
+ void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
+ {
+       unsigned long nulls1, nulls2;
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1937,6 +1937,17 @@ void tcp6_proc_exit(struct net *net)
+ }
+ #endif
++static void tcp_v6_clear_sk(struct sock *sk, int size)
++{
++      struct inet_sock *inet = inet_sk(sk);
++
++      /* we do not want to clear pinet6 field, because of RCU lookups */
++      sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6));
++
++      size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
++      memset(&inet->pinet6 + 1, 0, size);
++}
++
+ struct proto tcpv6_prot = {
+       .name                   = "TCPv6",
+       .owner                  = THIS_MODULE,
+@@ -1980,6 +1991,7 @@ struct proto tcpv6_prot = {
+ #ifdef CONFIG_MEMCG_KMEM
+       .proto_cgroup           = tcp_proto_cgroup,
+ #endif
++      .clear_sk               = tcp_v6_clear_sk,
+ };
+ static const struct inet6_protocol tcpv6_protocol = {
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1422,6 +1422,17 @@ void udp6_proc_exit(struct net *net) {
+ }
+ #endif /* CONFIG_PROC_FS */
++void udp_v6_clear_sk(struct sock *sk, int size)
++{
++      struct inet_sock *inet = inet_sk(sk);
++
++      /* we do not want to clear pinet6 field, because of RCU lookups */
++      sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6));
++
++      size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
++      memset(&inet->pinet6 + 1, 0, size);
++}
++
+ /* ------------------------------------------------------------------------ */
+ struct proto udpv6_prot = {
+@@ -1452,7 +1463,7 @@ struct proto udpv6_prot = {
+       .compat_setsockopt = compat_udpv6_setsockopt,
+       .compat_getsockopt = compat_udpv6_getsockopt,
+ #endif
+-      .clear_sk          = sk_prot_clear_portaddr_nulls,
++      .clear_sk          = udp_v6_clear_sk,
+ };
+ static struct inet_protosw udpv6_protosw = {
+--- a/net/ipv6/udp_impl.h
++++ b/net/ipv6/udp_impl.h
+@@ -31,6 +31,8 @@ extern int   udpv6_recvmsg(struct kiocb *i
+ extern int    udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
+ extern void   udpv6_destroy_sock(struct sock *sk);
++extern void udp_v6_clear_sk(struct sock *sk, int size);
++
+ #ifdef CONFIG_PROC_FS
+ extern int    udp6_seq_show(struct seq_file *seq, void *v);
+ #endif
+--- a/net/ipv6/udplite.c
++++ b/net/ipv6/udplite.c
+@@ -56,7 +56,7 @@ struct proto udplitev6_prot = {
+       .compat_setsockopt = compat_udpv6_setsockopt,
+       .compat_getsockopt = compat_udpv6_getsockopt,
+ #endif
+-      .clear_sk          = sk_prot_clear_portaddr_nulls,
++      .clear_sk          = udp_v6_clear_sk,
+ };
+ static struct inet_protosw udplite6_protosw = {
diff --git a/queue-3.9/ipv6-gre-do-not-leak-info-to-user-space.patch b/queue-3.9/ipv6-gre-do-not-leak-info-to-user-space.patch
new file mode 100644 (file)
index 0000000..35b5b50
--- /dev/null
@@ -0,0 +1,39 @@
+From fdc35e0619534b2733bb58e82fb5004942bc5725 Mon Sep 17 00:00:00 2001
+From: Amerigo Wang <amwang@redhat.com>
+Date: Thu, 9 May 2013 21:56:37 +0000
+Subject: ipv6,gre: do not leak info to user-space
+
+
+From: Amerigo Wang <amwang@redhat.com>
+
+[ Upstream commit 5dbd5068430b8bd1c19387d46d6c1a88b261257f ]
+
+There is a hole in struct ip6_tnl_parm2, so we have to
+zero the struct on stack before copying it to user-space.
+
+Cc: David S. Miller <davem@davemloft.net>
+Signed-off-by: Cong Wang <amwang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_gre.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -1135,6 +1135,7 @@ static int ip6gre_tunnel_ioctl(struct ne
+               }
+               if (t == NULL)
+                       t = netdev_priv(dev);
++              memset(&p, 0, sizeof(p));
+               ip6gre_tnl_parm_to_user(&p, &t->parms);
+               if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
+                       err = -EFAULT;
+@@ -1182,6 +1183,7 @@ static int ip6gre_tunnel_ioctl(struct ne
+               if (t) {
+                       err = 0;
++                      memset(&p, 0, sizeof(p));
+                       ip6gre_tnl_parm_to_user(&p, &t->parms);
+                       if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
+                               err = -EFAULT;
diff --git a/queue-3.9/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch b/queue-3.9/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
new file mode 100644 (file)
index 0000000..0b5f380
--- /dev/null
@@ -0,0 +1,79 @@
+From ead1543ee2fc73b466093c5696dd53cc23fe2634 Mon Sep 17 00:00:00 2001
+From: Jiri Pirko <jiri@resnulli.us>
+Date: Thu, 9 May 2013 04:23:40 +0000
+Subject: macvlan: fix passthru mode race between dev removal and rx path
+
+
+From: Jiri Pirko <jiri@resnulli.us>
+
+[ Upstream commit 233c7df0821c4190e2d3f4be0f2ca0ab40a5ed8c ]
+
+Currently, if macvlan in passthru mode is created and data are rxed and
+you remove this device, following panic happens:
+
+NULL pointer dereference at 0000000000000198
+IP: [<ffffffffa0196058>] macvlan_handle_frame+0x153/0x1f7 [macvlan]
+
+I'm using following script to trigger this:
+<script>
+while [ 1 ]
+do
+       ip link add link e1 name macvtap0 type macvtap mode passthru
+       ip link set e1 up
+       ip link set macvtap0 up
+       IFINDEX=`ip link |grep macvtap0 | cut -f 1 -d ':'`
+       cat /dev/tap$IFINDEX  >/dev/null &
+       ip link del dev macvtap0
+done
+</script>
+
+I run this script while "ping -f" is running on another machine to send
+packets to e1 rx.
+
+Reason of the panic is that list_first_entry() is blindly called in
+macvlan_handle_frame() even if the list was empty. vlan is set to
+incorrect pointer which leads to the crash.
+
+I'm fixing this by protecting port->vlans list by rcu and by preventing
+from getting incorrect pointer in case the list is empty.
+
+Introduced by: commit eb06acdc85585f2 "macvlan: Introduce 'passthru' mode to takeover the underlying device"
+
+Signed-off-by: Jiri Pirko <jiri@resnulli.us>
+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>
+---
+ drivers/net/macvlan.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -222,7 +222,8 @@ static rx_handler_result_t macvlan_handl
+       }
+       if (port->passthru)
+-              vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
++              vlan = list_first_or_null_rcu(&port->vlans,
++                                            struct macvlan_dev, list);
+       else
+               vlan = macvlan_hash_lookup(port, eth->h_dest);
+       if (vlan == NULL)
+@@ -807,7 +808,7 @@ int macvlan_common_newlink(struct net *s
+       if (err < 0)
+               goto upper_dev_unlink;
+-      list_add_tail(&vlan->list, &port->vlans);
++      list_add_tail_rcu(&vlan->list, &port->vlans);
+       netif_stacked_transfer_operstate(lowerdev, dev);
+       return 0;
+@@ -835,7 +836,7 @@ void macvlan_dellink(struct net_device *
+ {
+       struct macvlan_dev *vlan = netdev_priv(dev);
+-      list_del(&vlan->list);
++      list_del_rcu(&vlan->list);
+       unregister_netdevice_queue(dev, head);
+       netdev_upper_dev_unlink(vlan->lowerdev, dev);
+ }
diff --git a/queue-3.9/net-frag-fix-race-conditions-in-lru-list-maintenance.patch b/queue-3.9/net-frag-fix-race-conditions-in-lru-list-maintenance.patch
new file mode 100644 (file)
index 0000000..96d85ea
--- /dev/null
@@ -0,0 +1,122 @@
+From e2c580b27b7fdce751116f5c9e8585207f8cc5fe Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Date: Sun, 5 May 2013 04:56:22 +0000
+Subject: net: frag, fix race conditions in LRU list maintenance
+
+
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+
+[ Upstream commit b56141ab34e2c3e2d7960cea12c20c99530c0c76 ]
+
+This patch fixes race between inet_frag_lru_move() and inet_frag_lru_add()
+which was introduced in commit 3ef0eb0db4bf92c6d2510fe5c4dc51852746f206
+("net: frag, move LRU list maintenance outside of rwlock")
+
+One cpu already added new fragment queue into hash but not into LRU.
+Other cpu found it in hash and tries to move it to the end of LRU.
+This leads to NULL pointer dereference inside of list_move_tail().
+
+Another possible race condition is between inet_frag_lru_move() and
+inet_frag_lru_del(): move can happens after deletion.
+
+This patch initializes LRU list head before adding fragment into hash and
+inet_frag_lru_move() doesn't touches it if it's empty.
+
+I saw this kernel oops two times in a couple of days.
+
+[119482.128853] BUG: unable to handle kernel NULL pointer dereference at           (null)
+[119482.132693] IP: [<ffffffff812ede89>] __list_del_entry+0x29/0xd0
+[119482.136456] PGD 2148f6067 PUD 215ab9067 PMD 0
+[119482.140221] Oops: 0000 [#1] SMP
+[119482.144008] Modules linked in: vfat msdos fat 8021q fuse nfsd auth_rpcgss nfs_acl nfs lockd sunrpc ppp_async ppp_generic bridge slhc stp llc w83627ehf hwmon_vid snd_hda_codec_hdmi snd_hda_codec_realtek kvm_amd k10temp kvm snd_hda_intel snd_hda_codec edac_core radeon snd_hwdep ath9k snd_pcm ath9k_common snd_page_alloc ath9k_hw snd_timer snd soundcore drm_kms_helper ath ttm r8169 mii
+[119482.152692] CPU 3
+[119482.152721] Pid: 20, comm: ksoftirqd/3 Not tainted 3.9.0-zurg-00001-g9f95269 #132 To Be Filled By O.E.M. To Be Filled By O.E.M./RS880D
+[119482.161478] RIP: 0010:[<ffffffff812ede89>]  [<ffffffff812ede89>] __list_del_entry+0x29/0xd0
+[119482.166004] RSP: 0018:ffff880216d5db58  EFLAGS: 00010207
+[119482.170568] RAX: 0000000000000000 RBX: ffff88020882b9c0 RCX: dead000000200200
+[119482.175189] RDX: 0000000000000000 RSI: 0000000000000880 RDI: ffff88020882ba00
+[119482.179860] RBP: ffff880216d5db58 R08: ffffffff8155c7f0 R09: 0000000000000014
+[119482.184570] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88020882ba00
+[119482.189337] R13: ffffffff81c8d780 R14: ffff880204357f00 R15: 00000000000005a0
+[119482.194140] FS:  00007f58124dc700(0000) GS:ffff88021fcc0000(0000) knlGS:0000000000000000
+[119482.198928] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+[119482.203711] CR2: 0000000000000000 CR3: 00000002155f0000 CR4: 00000000000007e0
+[119482.208533] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[119482.213371] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+[119482.218221] Process ksoftirqd/3 (pid: 20, threadinfo ffff880216d5c000, task ffff880216d3a9a0)
+[119482.223113] Stack:
+[119482.228004]  ffff880216d5dbd8 ffffffff8155dcda 0000000000000000 ffff000200000001
+[119482.233038]  ffff8802153c1f00 ffff880000289440 ffff880200000014 ffff88007bc72000
+[119482.238083]  00000000000079d5 ffff88007bc72f44 ffffffff00000002 ffff880204357f00
+[119482.243090] Call Trace:
+[119482.248009]  [<ffffffff8155dcda>] ip_defrag+0x8fa/0xd10
+[119482.252921]  [<ffffffff815a8013>] ipv4_conntrack_defrag+0x83/0xe0
+[119482.257803]  [<ffffffff8154485b>] nf_iterate+0x8b/0xa0
+[119482.262658]  [<ffffffff8155c7f0>] ? inet_del_offload+0x40/0x40
+[119482.267527]  [<ffffffff815448e4>] nf_hook_slow+0x74/0x130
+[119482.272412]  [<ffffffff8155c7f0>] ? inet_del_offload+0x40/0x40
+[119482.277302]  [<ffffffff8155d068>] ip_rcv+0x268/0x320
+[119482.282147]  [<ffffffff81519992>] __netif_receive_skb_core+0x612/0x7e0
+[119482.286998]  [<ffffffff81519b78>] __netif_receive_skb+0x18/0x60
+[119482.291826]  [<ffffffff8151a650>] process_backlog+0xa0/0x160
+[119482.296648]  [<ffffffff81519f29>] net_rx_action+0x139/0x220
+[119482.301403]  [<ffffffff81053707>] __do_softirq+0xe7/0x220
+[119482.306103]  [<ffffffff81053868>] run_ksoftirqd+0x28/0x40
+[119482.310809]  [<ffffffff81074f5f>] smpboot_thread_fn+0xff/0x1a0
+[119482.315515]  [<ffffffff81074e60>] ? lg_local_lock_cpu+0x40/0x40
+[119482.320219]  [<ffffffff8106d870>] kthread+0xc0/0xd0
+[119482.324858]  [<ffffffff8106d7b0>] ? insert_kthread_work+0x40/0x40
+[119482.329460]  [<ffffffff816c32dc>] ret_from_fork+0x7c/0xb0
+[119482.334057]  [<ffffffff8106d7b0>] ? insert_kthread_work+0x40/0x40
+[119482.338661] 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 ad de 48 39 c8 74 7a <4c> 8b 00 4c 39 c7 75 53 4c 8b 42 08 4c 39 c7 75 2b 48 89 42 08
+[119482.343787] RIP  [<ffffffff812ede89>] __list_del_entry+0x29/0xd0
+[119482.348675]  RSP <ffff880216d5db58>
+[119482.353493] CR2: 0000000000000000
+
+Oops happened on this path:
+ip_defrag() -> ip_frag_queue() -> inet_frag_lru_move() -> list_move_tail() -> __list_del_entry()
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Cc: Jesper Dangaard Brouer <brouer@redhat.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: David S. Miller <davem@davemloft.net>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-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>
+---
+ include/net/inet_frag.h  |    5 +++--
+ net/ipv4/inet_fragment.c |    1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/include/net/inet_frag.h
++++ b/include/net/inet_frag.h
+@@ -135,14 +135,15 @@ static inline int sum_frag_mem_limit(str
+ static inline void inet_frag_lru_move(struct inet_frag_queue *q)
+ {
+       spin_lock(&q->net->lru_lock);
+-      list_move_tail(&q->lru_list, &q->net->lru_list);
++      if (!list_empty(&q->lru_list))
++              list_move_tail(&q->lru_list, &q->net->lru_list);
+       spin_unlock(&q->net->lru_lock);
+ }
+ static inline void inet_frag_lru_del(struct inet_frag_queue *q)
+ {
+       spin_lock(&q->net->lru_lock);
+-      list_del(&q->lru_list);
++      list_del_init(&q->lru_list);
+       spin_unlock(&q->net->lru_lock);
+ }
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -257,6 +257,7 @@ static struct inet_frag_queue *inet_frag
+       setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
+       spin_lock_init(&q->lock);
+       atomic_set(&q->refcnt, 1);
++      INIT_LIST_HEAD(&q->lru_list);
+       return q;
+ }
diff --git a/queue-3.9/net-mac802154-comparision-issue-of-type-cast-finding-by-extra_cflags-w.patch b/queue-3.9/net-mac802154-comparision-issue-of-type-cast-finding-by-extra_cflags-w.patch
new file mode 100644 (file)
index 0000000..72c866f
--- /dev/null
@@ -0,0 +1,36 @@
+From f0cd13a2baac658a8ce21427800ba4cc7867aa22 Mon Sep 17 00:00:00 2001
+From: Chen Gang <gang.chen@asianux.com>
+Date: Thu, 25 Apr 2013 00:49:55 +0000
+Subject: net: mac802154: comparision issue of type cast, finding by EXTRA_CFLAGS=-W
+
+
+From: Chen Gang <gang.chen@asianux.com>
+
+[ Upstream commit 2c1bbbffa0b644fab4f91878cde0c2e8f52e2dcc ]
+
+Change MAC802154_CHAN_NONE from ~(u8)0 to 0xff, or the comparison in
+mac802154_wpan_xmit() for ``chan == MAC802154_CHAN_NONE'' will not
+succeed.
+
+This bug can be boiled down to ``u8 foo = 0xff; if (foo == ~(u8)0)
+[...] else [...]'' where the condition will always take the else
+branch.
+
+Signed-off-by: Chen Gang <gang.chen@asianux.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac802154/mac802154.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac802154/mac802154.h
++++ b/net/mac802154/mac802154.h
+@@ -90,7 +90,7 @@ struct mac802154_sub_if_data {
+ #define MAC802154_MAX_XMIT_ATTEMPTS   3
+-#define MAC802154_CHAN_NONE           (~(u8)0) /* No channel is assigned */
++#define MAC802154_CHAN_NONE           0xff /* No channel is assigned */
+ extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced;
+ extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
diff --git a/queue-3.9/net-tun-release-the-reference-of-tun-device-in-tun_recvmsg.patch b/queue-3.9/net-tun-release-the-reference-of-tun-device-in-tun_recvmsg.patch
new file mode 100644 (file)
index 0000000..aba5af7
--- /dev/null
@@ -0,0 +1,44 @@
+From a8450dc36241a24946e108e79f691c4e4630accf Mon Sep 17 00:00:00 2001
+From: Gao feng <gaofeng@cn.fujitsu.com>
+Date: Wed, 24 Apr 2013 21:59:23 +0000
+Subject: net: tun: release the reference of tun device in tun_recvmsg
+
+
+From: Gao feng <gaofeng@cn.fujitsu.com>
+
+[ Upstream commit 3811ae76bc84e5dc1a670ae10695f046b310bee1 ]
+
+We forget to release the reference of tun device in tun_recvmsg.
+bug introduced in commit 54f968d6efdbf7dec36faa44fc11f01b0e4d1990
+(tuntap: move socket to tun_file)
+
+Signed-off-by: Gao feng <gaofeng@cn.fujitsu.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/tun.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1471,14 +1471,17 @@ static int tun_recvmsg(struct kiocb *ioc
+       if (!tun)
+               return -EBADFD;
+-      if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
+-              return -EINVAL;
++      if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) {
++              ret = -EINVAL;
++              goto out;
++      }
+       ret = tun_do_read(tun, tfile, iocb, m->msg_iov, total_len,
+                         flags & MSG_DONTWAIT);
+       if (ret > total_len) {
+               m->msg_flags |= MSG_TRUNC;
+               ret = flags & MSG_TRUNC ? ret : total_len;
+       }
++out:
+       tun_put(tun);
+       return ret;
+ }
diff --git a/queue-3.9/net-use-netdev_features_t-in-skb_needs_linearize.patch b/queue-3.9/net-use-netdev_features_t-in-skb_needs_linearize.patch
new file mode 100644 (file)
index 0000000..96b5e75
--- /dev/null
@@ -0,0 +1,28 @@
+From 06c31bcf7a2659ceb14483f1938a6d989586aea6 Mon Sep 17 00:00:00 2001
+From: Patrick McHardy <kaber@trash.net>
+Date: Wed, 1 May 2013 22:36:49 +0000
+Subject: net: use netdev_features_t in skb_needs_linearize()
+
+
+From: Patrick McHardy <kaber@trash.net>
+
+[ Upstream commit 6708c9e5cc9bfc7c9a00ce9c0fdd0b1d4952b3d1 ]
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2458,7 +2458,7 @@ EXPORT_SYMBOL(netif_skb_features);
+  *    2. skb is fragmented and the device does not support SG.
+  */
+ static inline int skb_needs_linearize(struct sk_buff *skb,
+-                                    int features)
++                                    netdev_features_t features)
+ {
+       return skb_is_nonlinear(skb) &&
+                       ((skb_has_frag_list(skb) &&
diff --git a/queue-3.9/net-vlan-ethtool-netdev_features_t-is-more-than-32-bit.patch b/queue-3.9/net-vlan-ethtool-netdev_features_t-is-more-than-32-bit.patch
new file mode 100644 (file)
index 0000000..38d082a
--- /dev/null
@@ -0,0 +1,40 @@
+From ea6506379511359807a25402272531a7c43c916e Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn@mork.no>
+Date: Wed, 1 May 2013 23:06:42 +0000
+Subject: net: vlan,ethtool: netdev_features_t is more than 32 bit
+
+
+From: Bjørn Mork <bjorn@mork.no>
+
+[ Upstream commit b29d3145183da4e07d4b570fa8acdd3ac4a5c572 ]
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/8021q/vlan_dev.c |    2 +-
+ net/core/ethtool.c   |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -627,7 +627,7 @@ static netdev_features_t vlan_dev_fix_fe
+       netdev_features_t features)
+ {
+       struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
+-      u32 old_features = features;
++      netdev_features_t old_features = features;
+       features &= real_dev->vlan_features;
+       features |= NETIF_F_RXCSUM;
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -1416,7 +1416,7 @@ int dev_ethtool(struct net *net, struct
+       void __user *useraddr = ifr->ifr_data;
+       u32 ethcmd;
+       int rc;
+-      u32 old_features;
++      netdev_features_t old_features;
+       if (!dev || !netif_device_present(dev))
+               return -ENODEV;
diff --git a/queue-3.9/net_sched-act_ipt-forward-compat-with-xtables.patch b/queue-3.9/net_sched-act_ipt-forward-compat-with-xtables.patch
new file mode 100644 (file)
index 0000000..b842e17
--- /dev/null
@@ -0,0 +1,78 @@
+From 1e40c6ebc0f1640b78e0f1f18d4ef0827d349512 Mon Sep 17 00:00:00 2001
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+Date: Sun, 28 Apr 2013 05:06:38 +0000
+Subject: net_sched: act_ipt forward compat with xtables
+
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 0dcffd09641f3abb21ac5cabc61542ab289d1a3c ]
+
+Deal with changes in newer xtables while maintaining backward
+compatibility. Thanks to Jan Engelhardt for suggestions.
+
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/act_ipt.c |   33 ++++++++++++++++++++++++++++++---
+ 1 file changed, 30 insertions(+), 3 deletions(-)
+
+--- a/net/sched/act_ipt.c
++++ b/net/sched/act_ipt.c
+@@ -8,7 +8,7 @@
+  *            as published by the Free Software Foundation; either version
+  *            2 of the License, or (at your option) any later version.
+  *
+- * Copyright: Jamal Hadi Salim (2002-4)
++ * Copyright: Jamal Hadi Salim (2002-13)
+  */
+ #include <linux/types.h>
+@@ -303,17 +303,44 @@ static struct tc_action_ops act_ipt_ops
+       .walk           =       tcf_generic_walker
+ };
+-MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
++static struct tc_action_ops act_xt_ops = {
++      .kind           =       "xt",
++      .hinfo          =       &ipt_hash_info,
++      .type           =       TCA_ACT_IPT,
++      .capab          =       TCA_CAP_NONE,
++      .owner          =       THIS_MODULE,
++      .act            =       tcf_ipt,
++      .dump           =       tcf_ipt_dump,
++      .cleanup        =       tcf_ipt_cleanup,
++      .lookup         =       tcf_hash_search,
++      .init           =       tcf_ipt_init,
++      .walk           =       tcf_generic_walker
++};
++
++MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
+ MODULE_DESCRIPTION("Iptables target actions");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("act_xt");
+ static int __init ipt_init_module(void)
+ {
+-      return tcf_register_action(&act_ipt_ops);
++      int ret1, ret2;
++      ret1 = tcf_register_action(&act_xt_ops);
++      if (ret1 < 0)
++              printk("Failed to load xt action\n");
++      ret2 = tcf_register_action(&act_ipt_ops);
++      if (ret2 < 0)
++              printk("Failed to load ipt action\n");
++
++      if (ret1 < 0 && ret2 < 0)
++              return ret1;
++      else
++              return 0;
+ }
+ static void __exit ipt_cleanup_module(void)
+ {
++      tcf_unregister_action(&act_xt_ops);
+       tcf_unregister_action(&act_ipt_ops);
+ }
diff --git a/queue-3.9/packet-tpacket_v3-do-not-trigger-bug-on-wrong-header-status.patch b/queue-3.9/packet-tpacket_v3-do-not-trigger-bug-on-wrong-header-status.patch
new file mode 100644 (file)
index 0000000..dfe6a09
--- /dev/null
@@ -0,0 +1,112 @@
+From 3acf910dded2f8a852b90d5b2fc55cd0537d72ca Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Fri, 3 May 2013 02:57:00 +0000
+Subject: packet: tpacket_v3: do not trigger bug() on wrong header status
+
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit 8da3056c04bfc5f69f840ab038a38389e2de8189 ]
+
+Jakub reported that it is fairly easy to trigger the BUG() macro
+from user space with TPACKET_V3's RX_RING by just giving a wrong
+header status flag. We already had a similar situation in commit
+7f5c3e3a80e6654 (``af_packet: remove BUG statement in
+tpacket_destruct_skb'') where this was the case in the TX_RING
+side that could be triggered from user space. So really, don't use
+BUG() or BUG_ON() unless there's really no way out, and i.e.
+don't use it for consistency checking when there's user space
+involved, no excuses, especially not if you're slapping the user
+with WARN + dump_stack + BUG all at once. The two functions are
+of concern:
+
+  prb_retire_current_block() [when block status != TP_STATUS_KERNEL]
+  prb_open_block() [when block_status != TP_STATUS_KERNEL]
+
+Calls to prb_open_block() are guarded by ealier checks if block_status
+is really TP_STATUS_KERNEL (racy!), but the first one BUG() is easily
+triggable from user space. System behaves still stable after they are
+removed. Also remove that yoda condition entirely, since it's already
+guarded.
+
+Reported-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/packet/af_packet.c |   53 +++++++++++++++++++++----------------------------
+ 1 file changed, 23 insertions(+), 30 deletions(-)
+
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -693,36 +693,33 @@ static void prb_open_block(struct tpacke
+       smp_rmb();
+-      if (likely(TP_STATUS_KERNEL == BLOCK_STATUS(pbd1))) {
++      /* We could have just memset this but we will lose the
++       * flexibility of making the priv area sticky
++       */
+-              /* We could have just memset this but we will lose the
+-               * flexibility of making the priv area sticky
+-               */
+-              BLOCK_SNUM(pbd1) = pkc1->knxt_seq_num++;
+-              BLOCK_NUM_PKTS(pbd1) = 0;
+-              BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
+-              getnstimeofday(&ts);
+-              h1->ts_first_pkt.ts_sec = ts.tv_sec;
+-              h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
+-              pkc1->pkblk_start = (char *)pbd1;
+-              pkc1->nxt_offset = pkc1->pkblk_start + BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
+-              BLOCK_O2FP(pbd1) = (__u32)BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
+-              BLOCK_O2PRIV(pbd1) = BLK_HDR_LEN;
+-              pbd1->version = pkc1->version;
+-              pkc1->prev = pkc1->nxt_offset;
+-              pkc1->pkblk_end = pkc1->pkblk_start + pkc1->kblk_size;
+-              prb_thaw_queue(pkc1);
+-              _prb_refresh_rx_retire_blk_timer(pkc1);
++      BLOCK_SNUM(pbd1) = pkc1->knxt_seq_num++;
++      BLOCK_NUM_PKTS(pbd1) = 0;
++      BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
+-              smp_wmb();
++      getnstimeofday(&ts);
+-              return;
+-      }
++      h1->ts_first_pkt.ts_sec = ts.tv_sec;
++      h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
++
++      pkc1->pkblk_start = (char *)pbd1;
++      pkc1->nxt_offset = pkc1->pkblk_start + BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
+-      WARN(1, "ERROR block:%p is NOT FREE status:%d kactive_blk_num:%d\n",
+-              pbd1, BLOCK_STATUS(pbd1), pkc1->kactive_blk_num);
+-      dump_stack();
+-      BUG();
++      BLOCK_O2FP(pbd1) = (__u32)BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
++      BLOCK_O2PRIV(pbd1) = BLK_HDR_LEN;
++
++      pbd1->version = pkc1->version;
++      pkc1->prev = pkc1->nxt_offset;
++      pkc1->pkblk_end = pkc1->pkblk_start + pkc1->kblk_size;
++
++      prb_thaw_queue(pkc1);
++      _prb_refresh_rx_retire_blk_timer(pkc1);
++
++      smp_wmb();
+ }
+ /*
+@@ -813,10 +810,6 @@ static void prb_retire_current_block(str
+               prb_close_block(pkc, pbd, po, status);
+               return;
+       }
+-
+-      WARN(1, "ERROR-pbd[%d]:%p\n", pkc->kactive_blk_num, pbd);
+-      dump_stack();
+-      BUG();
+ }
+ static int prb_curr_blk_in_use(struct tpacket_kbdq_core *pkc,
index a3716945745994ab6fe934e1db4f4fd28f7062bb..4bc5cbdf3131fc1d3463cbe8c1a8993c75a94bb4 100644 (file)
@@ -51,3 +51,24 @@ drm-mgag200-fix-framebuffer-base-address-programming.patch
 drm-mm-fix-dump-table-bug.patch
 drm-don-t-check-modeset-locks-in-panic-handler.patch
 drm-i915-clear-the-stolen-fb-before-resuming.patch
+tcp-force-a-dst-refcount-when-prequeue-packet.patch
+sfc-fix-naming-of-mtd-partitions-for-fpga-bitfiles.patch
+net-tun-release-the-reference-of-tun-device-in-tun_recvmsg.patch
+net-mac802154-comparision-issue-of-type-cast-finding-by-extra_cflags-w.patch
+tcp-reset-timer-after-any-synack-retransmit.patch
+3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
+net_sched-act_ipt-forward-compat-with-xtables.patch
+net-use-netdev_features_t-in-skb_needs_linearize.patch
+net-vlan-ethtool-netdev_features_t-is-more-than-32-bit.patch
+bridge-fix-race-with-topology-change-timer.patch
+asix-fix-bug-in-receive-path-when-lowering-mtu.patch
+packet-tpacket_v3-do-not-trigger-bug-on-wrong-header-status.patch
+virtio-don-t-expose-u16-in-userspace-api.patch
+net-frag-fix-race-conditions-in-lru-list-maintenance.patch
+3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
+3c59x-fix-pci-resource-management.patch
+if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
+macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
+ipv6-do-not-clear-pinet6-field.patch
+ipv6-gre-do-not-leak-info-to-user-space.patch
+xfrm6-release-dev-before-returning-error.patch
diff --git a/queue-3.9/sfc-fix-naming-of-mtd-partitions-for-fpga-bitfiles.patch b/queue-3.9/sfc-fix-naming-of-mtd-partitions-for-fpga-bitfiles.patch
new file mode 100644 (file)
index 0000000..6013d1f
--- /dev/null
@@ -0,0 +1,39 @@
+From f14df4da5e6e19094191b1384f6b69a45d174358 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Mon, 22 Apr 2013 22:40:07 +0100
+Subject: sfc: Fix naming of MTD partitions for FPGA bitfiles
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit 89cc80a44b7c320e08599cb86f6aef0ead8986a1 ]
+
+efx_mcdi_get_board_cfg() uses a buffer for the firmware response that
+is only large enough to hold subtypes for the originally defined set
+of NVRAM partitions.  Longer responses are truncated, and we may read
+off the end of the buffer when copying out subtypes for additional
+partitions.  In particular, this can result in the MTD partition for
+an FPGA bitfile being named e.g. 'eth5 sfc_fpga:00' when it should be
+'eth5 sfc_fpga:01'.  This means the firmware update tool (sfupdate)
+can't tell which bitfile should be written to the partition.
+
+Correct the response buffer size.
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/mcdi.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/sfc/mcdi.c
++++ b/drivers/net/ethernet/sfc/mcdi.c
+@@ -667,7 +667,7 @@ fail:
+ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
+                          u16 *fw_subtype_list, u32 *capabilities)
+ {
+-      uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN];
++      uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMAX];
+       size_t outlen, offset, i;
+       int port_num = efx_port_num(efx);
+       int rc;
diff --git a/queue-3.9/tcp-force-a-dst-refcount-when-prequeue-packet.patch b/queue-3.9/tcp-force-a-dst-refcount-when-prequeue-packet.patch
new file mode 100644 (file)
index 0000000..9996c81
--- /dev/null
@@ -0,0 +1,31 @@
+From c9566e83bd5ec922b5d19cabe4bf229b81a55de5 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 24 Apr 2013 18:34:55 -0700
+Subject: tcp: force a dst refcount when prequeue packet
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 093162553c33e9479283e107b4431378271c735d ]
+
+Before escaping RCU protected section and adding packet into
+prequeue, make sure the dst is refcounted.
+
+Reported-by: Mike Galbraith <bitbucket@online.de>
+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>
+---
+ include/net/tcp.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1049,6 +1049,7 @@ static inline bool tcp_prequeue(struct s
+           skb_queue_len(&tp->ucopy.prequeue) == 0)
+               return false;
++      skb_dst_force(skb);
+       __skb_queue_tail(&tp->ucopy.prequeue, skb);
+       tp->ucopy.memory += skb->truesize;
+       if (tp->ucopy.memory > sk->sk_rcvbuf) {
diff --git a/queue-3.9/tcp-reset-timer-after-any-synack-retransmit.patch b/queue-3.9/tcp-reset-timer-after-any-synack-retransmit.patch
new file mode 100644 (file)
index 0000000..6059743
--- /dev/null
@@ -0,0 +1,47 @@
+From 3dde7861ebc8d13c1bff35bf82f86df8f03674f0 Mon Sep 17 00:00:00 2001
+From: Yuchung Cheng <ycheng@google.com>
+Date: Mon, 29 Apr 2013 08:44:51 +0000
+Subject: tcp: reset timer after any SYNACK retransmit
+
+
+From: Yuchung Cheng <ycheng@google.com>
+
+[ Upstream commit cd75eff64dae8856afbf6ef0f0ca3c145465d8e0 ]
+
+Linux immediately returns SYNACK on (spurious) SYN retransmits, but
+keeps the SYNACK timer running independently. Thus the timer may
+fire right after the SYNACK retransmit and causes a SYN-SYNACK
+cross-fire burst.
+
+Adopt the fast retransmit/recovery idea in established state by
+re-arming the SYNACK timer after the fast (SYNACK) retransmit. The
+timer may fire late up to 500ms due to the current SYNACK timer wheel,
+but it's OK to be conservative when network is congested. Eric's new
+listener design should address this issue.
+
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_minisocks.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -583,8 +583,13 @@ struct sock *tcp_check_req(struct sock *
+                *
+                * Note that even if there is new data in the SYN packet
+                * they will be thrown away too.
++               *
++               * Reset timer after retransmitting SYNACK, similar to
++               * the idea of fast retransmit in recovery.
+                */
+-              inet_rtx_syn_ack(sk, req);
++              if (!inet_rtx_syn_ack(sk, req))
++                      req->expires = min(TCP_TIMEOUT_INIT << req->num_timeout,
++                                         TCP_RTO_MAX) + jiffies;
+               return NULL;
+       }
diff --git a/queue-3.9/virtio-don-t-expose-u16-in-userspace-api.patch b/queue-3.9/virtio-don-t-expose-u16-in-userspace-api.patch
new file mode 100644 (file)
index 0000000..a4ad42a
--- /dev/null
@@ -0,0 +1,39 @@
+From 948c8d59ef7602f98752e37d1ace34cdd89b3816 Mon Sep 17 00:00:00 2001
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Fri, 3 May 2013 14:49:41 +0000
+Subject: virtio: don't expose u16 in userspace api
+
+
+From: stephen hemminger <stephen@networkplumber.org>
+
+[ Upstream commit 77d21f23a1e4db8639e3916547c903a3b3c7a07c ]
+
+Programs using virtio headers outside of kernel will no longer
+build because u16 type does not exist in userspace. All user ABI
+must use __u16 typedef instead.
+
+Bug introduce by:
+  commit 986a4f4d452dec004697f667439d27c3fda9c928
+  Author: Jason Wang <jasowang@redhat.com>
+  Date:   Fri Dec 7 07:04:56 2012 +0000
+
+    virtio_net: multiqueue support
+
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/uapi/linux/virtio_net.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/virtio_net.h
++++ b/include/uapi/linux/virtio_net.h
+@@ -191,7 +191,7 @@ struct virtio_net_ctrl_mac {
+  * specified.
+  */
+ struct virtio_net_ctrl_mq {
+-      u16 virtqueue_pairs;
++      __u16 virtqueue_pairs;
+ };
+ #define VIRTIO_NET_CTRL_MQ   4
diff --git a/queue-3.9/xfrm6-release-dev-before-returning-error.patch b/queue-3.9/xfrm6-release-dev-before-returning-error.patch
new file mode 100644 (file)
index 0000000..0bdae39
--- /dev/null
@@ -0,0 +1,37 @@
+From 603f7aae63969465bc731a7c4670aa782df7a6ca Mon Sep 17 00:00:00 2001
+From: Cong Wang <amwang@redhat.com>
+Date: Thu, 9 May 2013 22:40:00 +0000
+Subject: xfrm6: release dev before returning error
+
+
+From: Cong Wang <amwang@redhat.com>
+
+[ Upstream commit 84c4a9dfbf430861e7588d95ae3ff61535dca351 ]
+
+We forget to call dev_put() on error path in xfrm6_fill_dst(),
+its caller doesn't handle this.
+
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: David S. Miller <davem@davemloft.net>
+Signed-off-by: Cong Wang <amwang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/xfrm6_policy.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -103,8 +103,10 @@ static int xfrm6_fill_dst(struct xfrm_ds
+       dev_hold(dev);
+       xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+-      if (!xdst->u.rt6.rt6i_idev)
++      if (!xdst->u.rt6.rt6i_idev) {
++              dev_put(dev);
+               return -ENODEV;
++      }
+       rt6_transfer_peer(&xdst->u.rt6, rt);