]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jan 2014 19:17:34 +0000 (11:17 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jan 2014 19:17:34 +0000 (11:17 -0800)
Pull networking updates from David Miller:

 1) BPF debugger and asm tool by Daniel Borkmann.

 2) Speed up create/bind in AF_PACKET, also from Daniel Borkmann.

 3) Correct reciprocal_divide and update users, from Hannes Frederic
    Sowa and Daniel Borkmann.

 4) Currently we only have a "set" operation for the hw timestamp socket
    ioctl, add a "get" operation to match.  From Ben Hutchings.

 5) Add better trace events for debugging driver datapath problems, also
    from Ben Hutchings.

 6) Implement auto corking in TCP, from Eric Dumazet.  Basically, if we
    have a small send and a previous packet is already in the qdisc or
    device queue, defer until TX completion or we get more data.

 7) Allow userspace to manage ipv6 temporary addresses, from Jiri Pirko.

 8) Add a qdisc bypass option for AF_PACKET sockets, from Daniel
    Borkmann.

 9) Share IP header compression code between Bluetooth and IEEE802154
    layers, from Jukka Rissanen.

10) Fix ipv6 router reachability probing, from Jiri Benc.

11) Allow packets to be captured on macvtap devices, from Vlad Yasevich.

12) Support tunneling in GRO layer, from Jerry Chu.

13) Allow bonding to be configured fully using netlink, from Scott
    Feldman.

14) Allow AF_PACKET users to obtain the VLAN TPID, just like they can
    already get the TCI.  From Atzm Watanabe.

15) New "Heavy Hitter" qdisc, from Terry Lam.

16) Significantly improve the IPSEC support in pktgen, from Fan Du.

17) Allow ipv4 tunnels to cache routes, just like sockets.  From Tom
    Herbert.

18) Add Proportional Integral Enhanced packet scheduler, from Vijay
    Subramanian.

19) Allow openvswitch to mmap'd netlink, from Thomas Graf.

20) Key TCP metrics blobs also by source address, not just destination
    address.  From Christoph Paasch.

21) Support 10G in generic phylib.  From Andy Fleming.

22) Try to short-circuit GRO flow compares using device provided RX
    hash, if provided.  From Tom Herbert.

The wireless and netfilter folks have been busy little bees too.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2064 commits)
  net/cxgb4: Fix referencing freed adapter
  ipv6: reallocate addrconf router for ipv6 address when lo device up
  fib_frontend: fix possible NULL pointer dereference
  rtnetlink: remove IFLA_BOND_SLAVE definition
  rtnetlink: remove check for fill_slave_info in rtnl_have_link_slave_info
  qlcnic: update version to 5.3.55
  qlcnic: Enhance logic to calculate msix vectors.
  qlcnic: Refactor interrupt coalescing code for all adapters.
  qlcnic: Update poll controller code path
  qlcnic: Interrupt code cleanup
  qlcnic: Enhance Tx timeout debugging.
  qlcnic: Use bool for rx_mac_learn.
  bonding: fix u64 division
  rtnetlink: add missing IFLA_BOND_AD_INFO_UNSPEC
  sfc: Use the correct maximum TX DMA ring size for SFC9100
  Add Shradha Shah as the sfc driver maintainer.
  net/vxlan: Share RX skb de-marking and checksum checks with ovs
  tulip: cleanup by using ARRAY_SIZE()
  ip_tunnel: clear IPCB in ip_tunnel_xmit() in case dst_link_failure() is called
  net/cxgb4: Don't retrieve stats during recovery
  ...

45 files changed:
1  2 
Documentation/devicetree/bindings/net/phy.txt
MAINTAINERS
arch/arc/include/asm/Kbuild
arch/arm64/include/asm/Kbuild
arch/cris/include/asm/Kbuild
arch/hexagon/include/asm/Kbuild
arch/microblaze/include/asm/Kbuild
arch/mn10300/include/asm/Kbuild
arch/parisc/include/asm/Kbuild
arch/score/include/asm/Kbuild
arch/xtensa/include/asm/Kbuild
drivers/infiniband/core/cma.c
drivers/net/bonding/bond_main.c
drivers/net/ethernet/8390/hydra.c
drivers/net/ethernet/8390/zorro8390.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/natsemi/macsonic.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/xen-netfront.c
drivers/phy/Kconfig
drivers/power/Kconfig
drivers/staging/ozwpan/ozproto.c
fs/dlm/lowcomms.c
include/linux/kernel.h
include/linux/mlx4/cmd.h
include/linux/mlx4/cq.h
include/linux/mlx4/device.h
include/linux/printk.h
include/linux/slab_def.h
include/net/netlabel.h
include/net/xfrm.h
include/uapi/linux/pci_regs.h
lib/Makefile
net/core/dev.c
net/core/netprio_cgroup.c
net/core/skbuff.c
net/ipv4/tcp.c
net/nfc/digital_dep.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c

index 85de6107b98f1fb834b7aaf979afdfc22a61c118,f648094abc35329bbb67114162e99ed289d90880..58307d0931c84294ec0ebfd75d6a215db4b5bf3f
@@@ -2,6 -2,7 +2,6 @@@ PHY node
  
  Required properties:
  
 - - device_type : Should be "ethernet-phy"
   - interrupts : <a b> where a is the interrupt number and b is a
     field that represents an encoding of the sense and level
     information for the interrupt.  This should be encoded based on
@@@ -10,6 -11,8 +10,6 @@@
   - interrupt-parent : the phandle for the interrupt controller that
     services interrupts for this device.
   - reg : The ID number for the phy, usually a small integer
 - - linux,phandle :  phandle for this node; likely referenced by an
 -   ethernet controller node.
  
  Optional Properties:
  
    specifications. If neither of these are specified, the default is to
    assume clause 22. The compatible list may also contain other
    elements.
+ - max-speed: Maximum PHY supported speed (10, 100, 1000...)
  
  Example:
  
  ethernet-phy@0 {
        compatible = "ethernet-phy-ieee802.3-c22";
 -      linux,phandle = <2452000>;
        interrupt-parent = <40000>;
        interrupts = <35 1>;
        reg = <0>;
 -      device_type = "ethernet-phy";
  };
diff --combined MAINTAINERS
index 8a777a235cc919d2d4638a3d8b554f5a294c0e5d,cd6e0a6a09a68ad5797c4fbe7f3eb8e2afb471b9..1912139a59a1f779d0d485d547458fb83ff8ea06
@@@ -93,11 -93,6 +93,11 @@@ Descriptions of section entries
        N: Files and directories with regex patterns.
           N:   [^a-z]tegra     all files whose path contains the word tegra
           One pattern per line.  Multiple N: lines acceptable.
 +         scripts/get_maintainer.pl has different behavior for files that
 +         match F: pattern and matches of N: patterns.  By default,
 +         get_maintainer will not look at git log history when an F: pattern
 +         match occurs.  When an N: match occurs, git log history is used
 +         to also notify the people that have git commit signatures.
        X: Files and directories that are NOT maintained, same rules as F:
           Files exclusions are tested before file matches.
           Can be useful for excluding a specific subdirectory, for instance:
@@@ -257,7 -252,6 +257,7 @@@ F: Documentation/ABI/testing/sysfs-bus-
  F:    drivers/pci/*acpi*
  F:    drivers/pci/*/*acpi*
  F:    drivers/pci/*/*/*acpi*
 +F:    tools/power/acpi
  
  ACPI COMPONENT ARCHITECTURE (ACPICA)
  M:    Robert Moore <robert.moore@intel.com>
@@@ -272,7 -266,6 +272,7 @@@ T: git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    drivers/acpi/acpica/
  F:    include/acpi/
 +F:    tools/power/acpi/
  
  ACPI FAN DRIVER
  M:    Zhang Rui <rui.zhang@intel.com>
@@@ -491,6 -484,7 +491,6 @@@ M: Hannes Reinecke <hare@suse.de
  L:    linux-scsi@vger.kernel.org
  S:    Maintained
  F:    drivers/scsi/aic7xxx/
 -F:    drivers/scsi/aic7xxx_old/
  
  AIMSLAB FM RADIO RECEIVER DRIVER
  M:    Hans Verkuil <hverkuil@xs4all.nl>
@@@ -545,13 -539,6 +545,13 @@@ F:       drivers/tty/serial/altera_jtaguart.
  F:    include/linux/altera_uart.h
  F:    include/linux/altera_jtaguart.h
  
 +AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
 +M:    Tom Lendacky <thomas.lendacky@amd.com>
 +L:    linux-crypto@vger.kernel.org
 +S:    Supported
 +F:    drivers/crypto/ccp/
 +F:    include/linux/ccp.h
 +
  AMD FAM15H PROCESSOR POWER MONITORING DRIVER
  M:    Andreas Herrmann <herrmann.der.user@googlemail.com>
  L:    lm-sensors@lm-sensors.org
@@@ -779,12 -766,7 +779,12 @@@ ARM/Allwinner A1X SoC suppor
  M:    Maxime Ripard <maxime.ripard@free-electrons.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
 -F:    arch/arm/mach-sunxi/
 +N:    sun[x4567]i
 +
 +ARM/Allwinner SoC Clock Support
 +M:    Emilio López <emilio@elopez.com.ar>
 +S:    Maintained
 +F:    drivers/clk/sunxi/
  
  ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
  M:    Andrew Victor <linux@maxim.org.za>
@@@ -885,12 -867,6 +885,12 @@@ S:       Maintaine
  F:    arch/arm/mach-ebsa110/
  F:    drivers/net/ethernet/amd/am79c961a.*
  
 +ARM/ENERGY MICRO (SILICON LABS) EFM32 SUPPORT
 +M:    Uwe Kleine-König <kernel@pengutronix.de>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +N:    efm32
 +
  ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
  M:    Daniel Ribeiro <drwyrm@gmail.com>
  M:    Stefan Schmidt <stefan@openezx.org>
@@@ -1053,12 -1029,6 +1053,12 @@@ L:    linux-arm-kernel@lists.infradead.or
  S:    Maintained
  F:    arch/arm/mach-mvebu/
  
 +ARM/Marvell Berlin SoC support
 +M:    Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm/mach-berlin/
 +
  ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support
  M:    Jason Cooper <jason@lakedaemon.net>
  M:    Andrew Lunn <andrew@lunn.ch>
@@@ -1352,14 -1322,6 +1352,14 @@@ F:    drivers/rtc/rtc-ab8500.
  F:    drivers/rtc/rtc-pl031.c
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
  
 +ARM/Ux500 CLOCK FRAMEWORK SUPPORT
 +M:    Ulf Hansson <ulf.hansson@linaro.org>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +T:    git git://git.linaro.org/people/ulfh/clk.git
 +S:    Maintained
 +F:    drivers/clk/ux500/
 +F:    include/linux/platform_data/clk-ux500.h
 +
  ARM/VFP SUPPORT
  M:    Russell King <linux@arm.linux.org.uk>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -1473,7 -1435,7 +1473,7 @@@ F:      Documentation/aoe
  F:    drivers/block/aoe/
  
  ATHEROS ATH GENERIC UTILITIES
- M:    "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
+ M:    "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
  L:    linux-wireless@vger.kernel.org
  S:    Supported
  F:    drivers/net/wireless/ath/*
  ATHEROS ATH5K WIRELESS DRIVER
  M:    Jiri Slaby <jirislaby@gmail.com>
  M:    Nick Kossifidis <mickflemm@gmail.com>
- M:    "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
+ M:    "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
  L:    linux-wireless@vger.kernel.org
  L:    ath5k-devel@lists.ath5k.org
  W:    http://wireless.kernel.org/en/users/Drivers/ath5k
@@@ -1496,17 -1458,6 +1496,6 @@@ T:     git git://github.com/kvalo/ath.gi
  S:    Supported
  F:    drivers/net/wireless/ath/ath6kl/
  
- ATHEROS ATH9K WIRELESS DRIVER
- M:    "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
- M:    Jouni Malinen <jouni@qca.qualcomm.com>
- M:    Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
- M:    Senthil Balasubramanian <senthilb@qca.qualcomm.com>
- L:    linux-wireless@vger.kernel.org
- L:    ath9k-devel@lists.ath9k.org
- W:    http://wireless.kernel.org/en/users/Drivers/ath9k
- S:    Supported
- F:    drivers/net/wireless/ath/ath9k/
  WILOCITY WIL6210 WIRELESS DRIVER
  M:    Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
  L:    linux-wireless@vger.kernel.org
@@@ -1636,10 -1587,11 +1625,10 @@@ S:      Supporte
  F:      drivers/scsi/esas2r
  
  AUDIT SUBSYSTEM
 -M:    Al Viro <viro@zeniv.linux.org.uk>
  M:    Eric Paris <eparis@redhat.com>
  L:    linux-audit@redhat.com (subscribers-only)
  W:    http://people.redhat.com/sgrubb/audit/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git
 +T:    git git://git.infradead.org/users/eparis/audit.git
  S:    Maintained
  F:    include/linux/audit.h
  F:    include/uapi/linux/audit.h
@@@ -2061,6 -2013,7 +2050,7 @@@ L:      linux-can@vger.kernel.or
  W:    http://gitorious.org/linux-can
  T:    git git://gitorious.org/linux-can/linux-can-next.git
  S:    Maintained
+ F:    Documentation/networking/can.txt
  F:    net/can/
  F:    include/linux/can/core.h
  F:    include/uapi/linux/can.h
@@@ -2195,11 -2148,6 +2185,11 @@@ M:    Nishank Trivedi <nistrive@cisco.com
  S:    Supported
  F:    drivers/net/ethernet/cisco/enic/
  
 +CISCO VIC LOW LATENCY NIC DRIVER
 +M:      Upinder Malhi <umalhi@cisco.com>
 +S:      Supported
 +F:      drivers/infiniband/hw/usnic
 +
  CIRRUS LOGIC EP93XX ETHERNET DRIVER
  M:    Hartley Sweeten <hsweeten@visionengravers.com>
  L:    netdev@vger.kernel.org
@@@ -2661,7 -2609,7 +2651,7 @@@ S:      Maintaine
  F:    drivers/platform/x86/dell-laptop.c
  
  DELL LAPTOP SMM DRIVER
 -S:    Orphan
 +M:    Guenter Roeck <linux@roeck-us.net>
  F:    drivers/char/i8k.c
  F:    include/uapi/linux/i8k.h
  
@@@ -2680,7 -2628,7 +2670,7 @@@ DESIGNWARE USB2 DRD IP DRIVE
  M:    Paul Zimmerman <paulz@synopsys.com>
  L:    linux-usb@vger.kernel.org
  S:    Maintained
 -F:    drivers/staging/dwc2/
 +F:    drivers/usb/dwc2/
  
  DESIGNWARE USB3 DRD IP DRIVER
  M:    Felipe Balbi <balbi@ti.com>
@@@ -3377,7 -3325,6 +3367,7 @@@ EXTERNAL CONNECTOR SUBSYSTEM (EXTCON
  M:    MyungJoo Ham <myungjoo.ham@samsung.com>
  M:    Chanwoo Choi <cw00.choi@samsung.com>
  L:    linux-kernel@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git
  S:    Maintained
  F:    drivers/extcon/
  F:    Documentation/extcon/
@@@ -3387,6 -3334,7 +3377,6 @@@ M:      Jingoo Han <jg1.han@samsung.com
  L:    linux-fbdev@vger.kernel.org
  S:    Maintained
  F:    drivers/video/exynos/exynos_dp*
 -F:    include/video/exynos_dp*
  
  EXYNOS MIPI DISPLAY DRIVERS
  M:    Inki Dae <inki.dae@samsung.com>
@@@ -3676,7 -3624,6 +3666,7 @@@ W:      http://en.wikipedia.org/wiki/F2F
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
  S:    Maintained
  F:    Documentation/filesystems/f2fs.txt
 +F:    Documentation/ABI/testing/sysfs-fs-f2fs
  F:    fs/f2fs/
  F:    include/linux/f2fs_fs.h
  
@@@ -3997,12 -3944,6 +3987,12 @@@ S:    Orpha
  F:    Documentation/filesystems/hfs.txt
  F:    fs/hfs/
  
 +HFSPLUS FILESYSTEM
 +L:    linux-fsdevel@vger.kernel.org
 +S:    Orphan
 +F:    Documentation/filesystems/hfsplus.txt
 +F:    fs/hfsplus/
 +
  HGA FRAMEBUFFER DRIVER
  M:    Ferenc Bakonyi <fero@drama.obuda.kando.hu>
  L:    linux-nvidia@lists.surfsouth.com
@@@ -4523,7 -4464,7 +4513,7 @@@ M:      Deepak Saxena <dsaxena@plexity.net
  S:    Maintained
  F:    drivers/char/hw_random/ixp4xx-rng.c
  
- INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf/i40e)
+ INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf/i40e/i40evf)
  M:    Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  M:    Jesse Brandeburg <jesse.brandeburg@intel.com>
  M:    Bruce Allan <bruce.w.allan@intel.com>
@@@ -4532,6 -4473,7 +4522,7 @@@ M:      Don Skidmore <donald.c.skidmore@inte
  M:    Greg Rose <gregory.v.rose@intel.com>
  M:    Alex Duyck <alexander.h.duyck@intel.com>
  M:    John Ronciak <john.ronciak@intel.com>
+ M:    Mitch Williams <mitch.a.williams@intel.com>
  L:    e1000-devel@lists.sourceforge.net
  W:    http://www.intel.com/support/feedback.htm
  W:    http://e1000.sourceforge.net/
@@@ -4547,6 -4489,7 +4538,7 @@@ F:      Documentation/networking/ixgb.tx
  F:    Documentation/networking/ixgbe.txt
  F:    Documentation/networking/ixgbevf.txt
  F:    Documentation/networking/i40e.txt
+ F:    Documentation/networking/i40evf.txt
  F:    drivers/net/ethernet/intel/
  
  INTEL-MID GPIO DRIVER
@@@ -4964,7 -4907,7 +4956,7 @@@ F:      include/linux/sunrpc
  F:    include/uapi/linux/sunrpc/
  
  KERNEL VIRTUAL MACHINE (KVM)
 -M:    Gleb Natapov <gleb@redhat.com>
 +M:    Gleb Natapov <gleb@kernel.org>
  M:    Paolo Bonzini <pbonzini@redhat.com>
  L:    kvm@vger.kernel.org
  W:    http://www.linux-kvm.org
@@@ -5190,11 -5133,6 +5182,11 @@@ F:    drivers/lguest
  F:    include/linux/lguest*.h
  F:    tools/lguest/
  
 +LIBLOCKDEP
 +M:    Sasha Levin <sasha.levin@oracle.com>
 +S:    Maintained
 +F:    tools/lib/lockdep/
 +
  LINUX FOR IBM pSERIES (RS/6000)
  M:    Paul Mackerras <paulus@au.ibm.com>
  W:    http://www.ibm.com/linux/ltc/projects/ppc
@@@ -6760,7 -6698,7 +6752,7 @@@ F:      include/linux/timer
  F:    kernel/*timer*
  
  POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
 -M:    Anton Vorontsov <anton@enomsg.org>
 +M:    Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
  M:    David Woodhouse <dwmw2@infradead.org>
  T:    git git://git.infradead.org/battery-2.6.git
  S:    Maintained
@@@ -6979,7 -6917,8 +6971,7 @@@ S:      Maintaine
  F:    drivers/scsi/qla1280.[ch]
  
  QLOGIC QLA2XXX FC-SCSI DRIVER
 -M:    Andrew Vasquez <andrew.vasquez@qlogic.com>
 -M:    linux-driver@qlogic.com
 +M:    qla2xxx-upstream@qlogic.com
  L:    linux-scsi@vger.kernel.org
  S:    Supported
  F:    Documentation/scsi/LICENSE.qla2xxx
@@@ -7041,6 -6980,14 +7033,14 @@@ T:    git git://linuxtv.org/anttip/media_t
  S:    Maintained
  F:    drivers/media/tuners/qt1010*
  
+ QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
+ M:    QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
+ L:    linux-wireless@vger.kernel.org
+ L:    ath9k-devel@lists.ath9k.org
+ W:    http://wireless.kernel.org/en/users/Drivers/ath9k
+ S:    Supported
+ F:    drivers/net/wireless/ath/ath9k/
  QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
  M:    Kalle Valo <kvalo@qca.qualcomm.com>
  L:    ath10k@lists.infradead.org
@@@ -7152,12 -7099,6 +7152,12 @@@ T:    git git://git.kernel.org/pub/scm/lin
  F:    Documentation/RCU/torture.txt
  F:    kernel/rcu/torture.c
  
 +RCUTORTURE TEST FRAMEWORK
 +M:    "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 +S:    Supported
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 +F:    tools/testing/selftests/rcutorture
 +
  RDC R-321X SoC
  M:    Florian Fainelli <florian@openwrt.org>
  S:    Maintained
@@@ -7456,12 -7397,6 +7456,12 @@@ L:    linux-media@vger.kernel.or
  S:    Supported
  F:    drivers/media/i2c/s5c73m3/*
  
 +SAMSUNG SOC CLOCK DRIVERS
 +M:    Tomasz Figa <t.figa@samsung.com>
 +S:    Supported
 +L:    linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 +F:    drivers/clk/samsung/
 +
  SERIAL DRIVERS
  M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  L:    linux-serial@vger.kernel.org
@@@ -7533,7 -7468,7 +7533,7 @@@ S:      Maintaine
  F:    drivers/scsi/sr*
  
  SCSI RDMA PROTOCOL (SRP) INITIATOR
 -M:    David Dillow <dillowda@ornl.gov>
 +M:    Bart Van Assche <bvanassche@acm.org>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  W:    http://www.openfabrics.org
@@@ -7545,9 -7480,8 +7545,9 @@@ F:      include/scsi/srp.
  SCSI SG DRIVER
  M:    Doug Gilbert <dgilbert@interlog.com>
  L:    linux-scsi@vger.kernel.org
 -W:    http://www.torque.net/sg
 +W:    http://sg.danny.cz/sg
  S:    Maintained
 +F:    Documentation/scsi/scsi-generic.txt
  F:    drivers/scsi/sg.c
  F:    include/scsi/sg.h
  
@@@ -7702,7 -7636,7 +7702,7 @@@ F:      drivers/net/ethernet/emulex/benet
  
  SFC NETWORK DRIVER
  M:    Solarflare linux maintainers <linux-net-drivers@solarflare.com>
- M:    Ben Hutchings <bhutchings@solarflare.com>
+ M:    Shradha Shah <sshah@solarflare.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    drivers/net/ethernet/sfc/
@@@ -8627,7 -8561,6 +8627,7 @@@ S:      Supporte
  F:      drivers/thermal/
  F:      include/linux/thermal.h
  F:      include/linux/cpu_cooling.h
 +F:      Documentation/devicetree/bindings/thermal/
  
  THINGM BLINK(1) USB RGB LED DRIVER
  M:    Vivien Didelot <vivien.didelot@savoirfairelinux.com>
@@@ -8695,12 -8628,11 +8695,11 @@@ S:   Maintaine
  F:    sound/soc/codecs/twl4030*
  
  TI WILINK WIRELESS DRIVERS
- M:    Luciano Coelho <luca@coelho.fi>
  L:    linux-wireless@vger.kernel.org
  W:    http://wireless.kernel.org/en/users/Drivers/wl12xx
  W:    http://wireless.kernel.org/en/users/Drivers/wl1251
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
- S:    Maintained
+ S:    Orphan
  F:    drivers/net/wireless/ti/
  F:    include/linux/wl12xx.h
  
@@@ -8801,10 -8733,14 +8800,10 @@@ S:   Odd fixe
  F:    drivers/media/usb/tm6000/
  
  TPM DEVICE DRIVER
 -M:    Leonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>
 -M:    Ashley Lai <ashley@ashleylai.com>
  M:    Peter Huewe <peterhuewe@gmx.de>
 -M:    Rajiv Andrade <mail@srajiv.net>
 -W:    http://tpmdd.sourceforge.net
 +M:    Ashley Lai <ashley@ashleylai.com>
  M:    Marcel Selhorst <tpmdd@selhorst.net>
 -M:    Sirrix AG <tpmdd@sirrix.com>
 -W:    http://www.sirrix.com
 +W:    http://tpmdd.sourceforge.net
  L:    tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
  S:    Maintained
  F:    drivers/char/tpm/
@@@ -9615,7 -9551,6 +9614,7 @@@ M:      Konrad Rzeszutek Wilk <konrad.wilk@o
  M:    Boris Ostrovsky <boris.ostrovsky@oracle.com>
  M:    David Vrabel <david.vrabel@citrix.com>
  L:    xen-devel@lists.xenproject.org (moderated for non-subscribers)
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
  S:    Supported
  F:    arch/x86/xen/
  F:    drivers/*/xen-*front.c
index 9ae21c198007758b07cde32b2b06eebd271d4ec5,cf29d84fd9c2e6bfd904771c77d6bf76e689b16d..0d3362991c316efd8236933c178523565c3f29ad
@@@ -1,5 -1,4 +1,5 @@@
  generic-y += auxvec.h
 +generic-y += barrier.h
  generic-y += bugs.h
  generic-y += bitsperlong.h
  generic-y += clkdev.h
@@@ -12,6 -11,7 +12,7 @@@ generic-y += fcntl.
  generic-y += fb.h
  generic-y += ftrace.h
  generic-y += hardirq.h
+ generic-y += hash.h
  generic-y += hw_irq.h
  generic-y += ioctl.h
  generic-y += ioctls.h
index d0ff25de67cade78ed5ad9309c58135494b53f48,626d4a92521f7b49f6bfca4c45f63428a04de05a..71c53ecfcc3ae356f0c5d0bd4c593e3b7bef8b89
@@@ -26,6 -26,7 +26,6 @@@ generic-y += mman.
  generic-y += msgbuf.h
  generic-y += mutex.h
  generic-y += pci.h
 -generic-y += percpu.h
  generic-y += poll.h
  generic-y += posix_types.h
  generic-y += resource.h
@@@ -50,3 -51,4 +50,4 @@@ generic-y += user.
  generic-y += vga.h
  generic-y += xor.h
  generic-y += preempt.h
+ generic-y += hash.h
index 199b1a9dab8922b307cca53b1d2dbf3ccf83faee,406cbd3ebd5849cb485861b8f5488ab1550686ee..f3fd8768f095cc55c606d22bf5281042a31234c2
@@@ -3,9 -3,9 +3,10 @@@ header-y += arch-v10
  header-y += arch-v32/
  
  
 +generic-y += barrier.h
  generic-y += clkdev.h
  generic-y += exec.h
+ generic-y += hash.h
  generic-y += kvm_para.h
  generic-y += linkage.h
  generic-y += module.h
index ada843c701ef56380c40d0cba6a611752542335c,ae45d75a3187e0e4bb17c60d56caf61ba9a6395d..38ca45d3df1e4d88230d1ab8f991510efb983450
@@@ -2,7 -2,6 +2,7 @@@
  header-y += ucontext.h
  
  generic-y += auxvec.h
 +generic-y += barrier.h
  generic-y += bug.h
  generic-y += bugs.h
  generic-y += clkdev.h
@@@ -16,6 -15,7 +16,7 @@@ generic-y += fb.
  generic-y += fcntl.h
  generic-y += ftrace.h
  generic-y += hardirq.h
+ generic-y += hash.h
  generic-y += hw_irq.h
  generic-y += ioctl.h
  generic-y += ioctls.h
index a82426589fffb2cb9bf440b1d44ad73eab8002f9,ca60945ddf307cddaef5989df64258db8638362d..2b98bc73642afb4cd07c7c412c416c9a87cb69de
@@@ -1,7 -1,7 +1,8 @@@
  
 +generic-y += barrier.h
  generic-y += clkdev.h
  generic-y += exec.h
+ generic-y += hash.h
  generic-y += trace_clock.h
  generic-y += syscalls.h
  generic-y += preempt.h
index 032143ec23245113fd0394c8a5d26dfc134ea29e,199345207d8292f56118c8bc39b74584ad4a1dde..992e989ab7853d3f3e1be4bbb432cf4c2de8c7a2
@@@ -1,6 -1,6 +1,7 @@@
  
 +generic-y += barrier.h
  generic-y += clkdev.h
  generic-y += exec.h
+ generic-y += hash.h
  generic-y += trace_clock.h
  generic-y += preempt.h
index 34b0be4ca52d7728137b4651a55b35b12420c344,75edd5fcc6ff12822ca4d3dd5d9d419eea1302b9..752c981bc3c7fc36dbd0fb01705f4c691e7ee6bd
@@@ -1,8 -1,8 +1,9 @@@
  
 +generic-y += barrier.h
  generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \
          segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \
          div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \
          poll.h xor.h clkdev.h exec.h
  generic-y += trace_clock.h
  generic-y += preempt.h
+ generic-y += hash.h
index fe7471eb0167cb92e313d86169f0b77e964845df,1d35e33ccf8688364a5be12c4b6aac734c50e942..146b9d5e89f83ba0b41506aa369254d5869dbe88
@@@ -1,8 -1,9 +1,10 @@@
  
  header-y +=
  
 +generic-y += barrier.h
  generic-y += clkdev.h
+ generic-y += hash.h
  generic-y += trace_clock.h
  generic-y += xor.h
  generic-y += preempt.h
index 5851db291583face7d032c2929dd5c91b58204d6,d7efa1502101b32fb77f53297173f7da81e16959..0a337e4a8370aefce9d310c47bf75053316a1d5a
@@@ -8,6 -8,7 +8,6 @@@ generic-y += emergency-restart.
  generic-y += errno.h
  generic-y += exec.h
  generic-y += fcntl.h
 -generic-y += futex.h
  generic-y += hardirq.h
  generic-y += ioctl.h
  generic-y += irq_regs.h
@@@ -28,3 -29,4 +28,4 @@@ generic-y += topology.
  generic-y += trace_clock.h
  generic-y += xor.h
  generic-y += preempt.h
+ generic-y += hash.h
index 9b079a7ea29c68d5875b8ae29473d47b925c520f,6c17f2dc0f09d8a587ef812b4be70645390a3257..199958d9ddc8088d7576904ab96c838fb193990c
@@@ -340,7 -340,7 +340,7 @@@ static int cma_translate_addr(struct so
        int ret;
  
        if (addr->sa_family != AF_IB) {
 -              ret = rdma_translate_ip(addr, dev_addr);
 +              ret = rdma_translate_ip(addr, dev_addr, NULL);
        } else {
                cma_translate_ib((struct sockaddr_ib *) addr, dev_addr);
                ret = 0;
@@@ -365,9 -365,7 +365,9 @@@ static int cma_acquire_dev(struct rdma_
                return -EINVAL;
  
        mutex_lock(&lock);
 -      iboe_addr_get_sgid(dev_addr, &iboe_gid);
 +      rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
 +                  &iboe_gid);
 +
        memcpy(&gid, dev_addr->src_dev_addr +
               rdma_addr_gid_offset(dev_addr), sizeof gid);
        if (listen_id_priv &&
@@@ -605,7 -603,6 +605,7 @@@ static int cma_modify_qp_rtr(struct rdm
  {
        struct ib_qp_attr qp_attr;
        int qp_attr_mask, ret;
 +      union ib_gid sgid;
  
        mutex_lock(&id_priv->qp_mutex);
        if (!id_priv->id.qp) {
        if (ret)
                goto out;
  
 +      ret = ib_query_gid(id_priv->id.device, id_priv->id.port_num,
 +                         qp_attr.ah_attr.grh.sgid_index, &sgid);
 +      if (ret)
 +              goto out;
 +
 +      if (rdma_node_get_transport(id_priv->cma_dev->device->node_type)
 +          == RDMA_TRANSPORT_IB &&
 +          rdma_port_get_link_layer(id_priv->id.device, id_priv->id.port_num)
 +          == IB_LINK_LAYER_ETHERNET) {
 +              ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr.smac, NULL);
 +
 +              if (ret)
 +                      goto out;
 +      }
        if (conn_param)
                qp_attr.max_dest_rd_atomic = conn_param->responder_resources;
        ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
@@@ -742,7 -725,6 +742,7 @@@ int rdma_init_qp_attr(struct rdma_cm_i
                else
                        ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
                                                 qp_attr_mask);
 +
                if (qp_attr->qp_state == IB_QPS_RTR)
                        qp_attr->rq_psn = id_priv->seq_num;
                break;
@@@ -1284,15 -1266,6 +1284,15 @@@ static int cma_req_handler(struct ib_cm
        struct rdma_id_private *listen_id, *conn_id;
        struct rdma_cm_event event;
        int offset, ret;
 +      u8 smac[ETH_ALEN];
 +      u8 alt_smac[ETH_ALEN];
 +      u8 *psmac = smac;
 +      u8 *palt_smac = alt_smac;
 +      int is_iboe = ((rdma_node_get_transport(cm_id->device->node_type) ==
 +                      RDMA_TRANSPORT_IB) &&
 +                     (rdma_port_get_link_layer(cm_id->device,
 +                      ib_event->param.req_rcvd.port) ==
 +                      IB_LINK_LAYER_ETHERNET));
  
        listen_id = cm_id->context;
        if (!cma_check_req_qp_type(&listen_id->id, ib_event))
        if (ret)
                goto err3;
  
 +      if (is_iboe) {
 +              if (ib_event->param.req_rcvd.primary_path != NULL)
 +                      rdma_addr_find_smac_by_sgid(
 +                              &ib_event->param.req_rcvd.primary_path->sgid,
 +                              psmac, NULL);
 +              else
 +                      psmac = NULL;
 +              if (ib_event->param.req_rcvd.alternate_path != NULL)
 +                      rdma_addr_find_smac_by_sgid(
 +                              &ib_event->param.req_rcvd.alternate_path->sgid,
 +                              palt_smac, NULL);
 +              else
 +                      palt_smac = NULL;
 +      }
        /*
         * Acquire mutex to prevent user executing rdma_destroy_id()
         * while we're accessing the cm_id.
         */
        mutex_lock(&lock);
 -      if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD))
 +      if (is_iboe)
 +              ib_update_cm_av(cm_id, psmac, palt_smac);
 +      if (cma_comp(conn_id, RDMA_CM_CONNECT) &&
 +          (conn_id->id.qp_type != IB_QPT_UD))
                ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
        mutex_unlock(&lock);
        mutex_unlock(&conn_id->handler_mutex);
@@@ -1518,7 -1474,7 +1518,7 @@@ static int iw_conn_req_handler(struct i
        mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
        conn_id->state = RDMA_CM_CONNECT;
  
 -      ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr);
 +      ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr, NULL);
        if (ret) {
                mutex_unlock(&conn_id->handler_mutex);
                rdma_destroy_id(new_cm_id);
@@@ -1917,7 -1873,7 +1917,7 @@@ static int cma_resolve_iboe_route(struc
        struct cma_work *work;
        int ret;
        struct net_device *ndev = NULL;
 -      u16 vid;
 +
  
        work = kzalloc(sizeof *work, GFP_KERNEL);
        if (!work)
                goto err2;
        }
  
 -      vid = rdma_vlan_dev_vlan_id(ndev);
 +      route->path_rec->vlan_id = rdma_vlan_dev_vlan_id(ndev);
 +      memcpy(route->path_rec->dmac, addr->dev_addr.dst_dev_addr, ETH_ALEN);
 +      memcpy(route->path_rec->smac, ndev->dev_addr, ndev->addr_len);
  
 -      iboe_mac_vlan_to_ll(&route->path_rec->sgid, addr->dev_addr.src_dev_addr, vid);
 -      iboe_mac_vlan_to_ll(&route->path_rec->dgid, addr->dev_addr.dst_dev_addr, vid);
 +      rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
 +                  &route->path_rec->sgid);
 +      rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.dst_addr,
 +                  &route->path_rec->dgid);
  
        route->path_rec->hop_limit = 1;
        route->path_rec->reversible = 1;
@@@ -2111,7 -2063,6 +2111,7 @@@ static void addr_handler(int status, st
                           RDMA_CM_ADDR_RESOLVED))
                goto out;
  
 +      memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
        if (!status && !id_priv->cma_dev)
                status = cma_acquire_dev(id_priv, NULL);
  
                        goto out;
                event.event = RDMA_CM_EVENT_ADDR_ERROR;
                event.status = status;
 -      } else {
 -              memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
 +      } else
                event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
 -      }
  
        if (id_priv->id.event_handler(&id_priv->id, &event)) {
                cma_exch(id_priv, RDMA_CM_DESTROYING);
@@@ -2357,7 -2310,7 +2357,7 @@@ static int cma_alloc_any_port(struct id
  
        inet_get_local_port_range(&init_net, &low, &high);
        remaining = (high - low) + 1;
-       rover = net_random() % remaining + low;
+       rover = prandom_u32() % remaining + low;
  retry:
        if (last_used_port != rover &&
            !idr_find(ps, (unsigned short) rover)) {
@@@ -2527,11 -2480,8 +2527,11 @@@ static int cma_check_linklocal(struct r
                return 0;
  
        sin6 = (struct sockaddr_in6 *) addr;
 -      if ((ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
 -          !sin6->sin6_scope_id)
 +
 +      if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
 +              return 0;
 +
 +      if (!sin6->sin6_scope_id)
                        return -EINVAL;
  
        dev_addr->bound_dev_if = sin6->sin6_scope_id;
@@@ -2606,7 -2556,6 +2606,7 @@@ int rdma_bind_addr(struct rdma_cm_id *i
        if (ret)
                goto err1;
  
 +      memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
        if (!cma_any_addr(addr)) {
                ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
                if (ret)
                        goto err1;
        }
  
 -      memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
        if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) {
                if (addr->sa_family == AF_INET)
                        id_priv->afonly = 1;
@@@ -3345,8 -3295,7 +3345,8 @@@ static int cma_iboe_join_multicast(stru
                err = -EINVAL;
                goto out2;
        }
 -      iboe_addr_get_sgid(dev_addr, &mc->multicast.ib->rec.port_gid);
 +      rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
 +                  &mc->multicast.ib->rec.port_gid);
        work->id = id_priv;
        work->mc = mc;
        INIT_WORK(&work->work, iboe_mcast_work_handler);
index 6191b551a0e83b9083bc17d70a302956af0ed296,f9e0c8bbfa41e91915eb05e3172257652cad9f9c..a7db819bca9278356598152060c4684bd6f615c7
@@@ -79,7 -79,6 +79,6 @@@
  #include <net/pkt_sched.h>
  #include <linux/rculist.h>
  #include <net/flow_keys.h>
- #include <linux/reciprocal_div.h>
  #include "bonding.h"
  #include "bond_3ad.h"
  #include "bond_alb.h"
  /*---------------------------- Module parameters ----------------------------*/
  
  /* monitor all links that often (in milliseconds). <=0 disables monitoring */
- #define BOND_LINK_MON_INTERV  0
- #define BOND_LINK_ARP_INTERV  0
  
  static int max_bonds  = BOND_DEFAULT_MAX_BONDS;
  static int tx_queues  = BOND_DEFAULT_TX_QUEUES;
  static int num_peer_notif = 1;
- static int miimon     = BOND_LINK_MON_INTERV;
+ static int miimon;
  static int updelay;
  static int downdelay;
  static int use_carrier        = 1;
@@@ -104,7 -101,7 +101,7 @@@ static char *lacp_rate
  static int min_links;
  static char *ad_select;
  static char *xmit_hash_policy;
- static int arp_interval = BOND_LINK_ARP_INTERV;
+ static int arp_interval;
  static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
  static char *arp_validate;
  static char *arp_all_targets;
@@@ -113,6 -110,7 +110,7 @@@ static int all_slaves_active
  static struct bond_params bonding_defaults;
  static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
  static int packets_per_slave = 1;
+ static int lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
  
  module_param(max_bonds, int, 0);
  MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@@ -189,6 -187,10 +187,10 @@@ module_param(packets_per_slave, int, 0)
  MODULE_PARM_DESC(packets_per_slave, "Packets to send per slave in balance-rr "
                                    "mode; 0 for a random slave, 1 packet per "
                                    "slave (default), >1 packets per slave.");
+ module_param(lp_interval, uint, 0);
+ MODULE_PARM_DESC(lp_interval, "The number of seconds between instances where "
+                             "the bonding driver sends learning packets to "
+                             "each slaves peer switch. The default is 1.");
  
  /*----------------------------- Global variables ----------------------------*/
  
@@@ -204,67 -206,6 +206,6 @@@ static int bond_mode      = BOND_MODE_ROUNDR
  static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
  static int lacp_fast;
  
- const struct bond_parm_tbl bond_lacp_tbl[] = {
- {     "slow",         AD_LACP_SLOW},
- {     "fast",         AD_LACP_FAST},
- {     NULL,           -1},
- };
- const struct bond_parm_tbl bond_mode_tbl[] = {
- {     "balance-rr",           BOND_MODE_ROUNDROBIN},
- {     "active-backup",        BOND_MODE_ACTIVEBACKUP},
- {     "balance-xor",          BOND_MODE_XOR},
- {     "broadcast",            BOND_MODE_BROADCAST},
- {     "802.3ad",              BOND_MODE_8023AD},
- {     "balance-tlb",          BOND_MODE_TLB},
- {     "balance-alb",          BOND_MODE_ALB},
- {     NULL,                   -1},
- };
- const struct bond_parm_tbl xmit_hashtype_tbl[] = {
- {     "layer2",               BOND_XMIT_POLICY_LAYER2},
- {     "layer3+4",             BOND_XMIT_POLICY_LAYER34},
- {     "layer2+3",             BOND_XMIT_POLICY_LAYER23},
- {     "encap2+3",             BOND_XMIT_POLICY_ENCAP23},
- {     "encap3+4",             BOND_XMIT_POLICY_ENCAP34},
- {     NULL,                   -1},
- };
- const struct bond_parm_tbl arp_all_targets_tbl[] = {
- {     "any",                  BOND_ARP_TARGETS_ANY},
- {     "all",                  BOND_ARP_TARGETS_ALL},
- {     NULL,                   -1},
- };
- const struct bond_parm_tbl arp_validate_tbl[] = {
- {     "none",                 BOND_ARP_VALIDATE_NONE},
- {     "active",               BOND_ARP_VALIDATE_ACTIVE},
- {     "backup",               BOND_ARP_VALIDATE_BACKUP},
- {     "all",                  BOND_ARP_VALIDATE_ALL},
- {     NULL,                   -1},
- };
- const struct bond_parm_tbl fail_over_mac_tbl[] = {
- {     "none",                 BOND_FOM_NONE},
- {     "active",               BOND_FOM_ACTIVE},
- {     "follow",               BOND_FOM_FOLLOW},
- {     NULL,                   -1},
- };
- const struct bond_parm_tbl pri_reselect_tbl[] = {
- {     "always",               BOND_PRI_RESELECT_ALWAYS},
- {     "better",               BOND_PRI_RESELECT_BETTER},
- {     "failure",              BOND_PRI_RESELECT_FAILURE},
- {     NULL,                   -1},
- };
- struct bond_parm_tbl ad_select_tbl[] = {
- {     "stable",       BOND_AD_STABLE},
- {     "bandwidth",    BOND_AD_BANDWIDTH},
- {     "count",        BOND_AD_COUNT},
- {     NULL,           -1},
- };
  /*-------------------------- Forward declarations ---------------------------*/
  
  static int bond_init(struct net_device *bond_dev);
@@@ -299,7 -240,7 +240,7 @@@ const char *bond_mode_name(int mode
   * @skb: hw accel VLAN tagged skb to transmit
   * @slave_dev: slave that is supposed to xmit this skbuff
   */
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
                        struct net_device *slave_dev)
  {
        skb->dev = slave_dev;
                bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
        else
                dev_queue_xmit(skb);
-       return 0;
  }
  
  /*
@@@ -463,6 -402,22 +402,22 @@@ static void bond_update_speed_duplex(st
        return;
  }
  
+ const char *bond_slave_link_status(s8 link)
+ {
+       switch (link) {
+       case BOND_LINK_UP:
+               return "up";
+       case BOND_LINK_FAIL:
+               return "going down";
+       case BOND_LINK_DOWN:
+               return "down";
+       case BOND_LINK_BACK:
+               return "going back";
+       default:
+               return "unknown";
+       }
+ }
  /*
   * if <dev> supports MII link status reporting, check its link status.
   *
@@@ -591,33 -546,22 +546,22 @@@ static int bond_set_allmulti(struct bon
   * device and retransmit an IGMP JOIN request to the current active
   * slave.
   */
- static void bond_resend_igmp_join_requests(struct bonding *bond)
+ static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
  {
+       struct bonding *bond = container_of(work, struct bonding,
+                                           mcast_work.work);
        if (!rtnl_trylock()) {
                queue_delayed_work(bond->wq, &bond->mcast_work, 1);
                return;
        }
        call_netdevice_notifiers(NETDEV_RESEND_IGMP, bond->dev);
-       rtnl_unlock();
  
-       /* We use curr_slave_lock to protect against concurrent access to
-        * igmp_retrans from multiple running instances of this function and
-        * bond_change_active_slave
-        */
-       write_lock_bh(&bond->curr_slave_lock);
        if (bond->igmp_retrans > 1) {
                bond->igmp_retrans--;
                queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
        }
-       write_unlock_bh(&bond->curr_slave_lock);
- }
- static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
- {
-       struct bonding *bond = container_of(work, struct bonding,
-                                           mcast_work.work);
-       bond_resend_igmp_join_requests(bond);
+       rtnl_unlock();
  }
  
  /* Flush bond's hardware addresses from slave
@@@ -697,14 -641,12 +641,12 @@@ static void bond_set_dev_addr(struct ne
   *
   * Perform special MAC address swapping for fail_over_mac settings
   *
-  * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh.
+  * Called with RTNL, curr_slave_lock for write_bh.
   */
  static void bond_do_fail_over_mac(struct bonding *bond,
                                  struct slave *new_active,
                                  struct slave *old_active)
        __releases(&bond->curr_slave_lock)
-       __releases(&bond->lock)
-       __acquires(&bond->lock)
        __acquires(&bond->curr_slave_lock)
  {
        u8 tmp_mac[ETH_ALEN];
        case BOND_FOM_ACTIVE:
                if (new_active) {
                        write_unlock_bh(&bond->curr_slave_lock);
-                       read_unlock(&bond->lock);
                        bond_set_dev_addr(bond->dev, new_active->dev);
-                       read_lock(&bond->lock);
                        write_lock_bh(&bond->curr_slave_lock);
                }
                break;
                        return;
  
                write_unlock_bh(&bond->curr_slave_lock);
-               read_unlock(&bond->lock);
  
                if (old_active) {
                        memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
                        pr_err("%s: Error %d setting MAC of slave %s\n",
                               bond->dev->name, -rv, new_active->dev->name);
  out:
-               read_lock(&bond->lock);
                write_lock_bh(&bond->curr_slave_lock);
                break;
        default:
@@@ -821,7 -759,11 +759,11 @@@ static struct slave *bond_find_best_sla
  
  static bool bond_should_notify_peers(struct bonding *bond)
  {
-       struct slave *slave = bond->curr_active_slave;
+       struct slave *slave;
+       rcu_read_lock();
+       slave = rcu_dereference(bond->curr_active_slave);
+       rcu_read_unlock();
  
        pr_debug("bond_should_notify_peers: bond %s slave %s\n",
                 bond->dev->name, slave ? slave->dev->name : "NULL");
   * because it is apparently the best available slave we have, even though its
   * updelay hasn't timed out yet.
   *
-  * If new_active is not NULL, caller must hold bond->lock for read and
-  * curr_slave_lock for write_bh.
+  * If new_active is not NULL, caller must hold curr_slave_lock for write_bh.
   */
  void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
  {
                        }
  
                        write_unlock_bh(&bond->curr_slave_lock);
-                       read_unlock(&bond->lock);
  
                        call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
                        if (should_notify_peers)
                                call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
                                                         bond->dev);
  
-                       read_lock(&bond->lock);
                        write_lock_bh(&bond->curr_slave_lock);
                }
        }
   * - The primary_slave has got its link back.
   * - A slave has got its link back and there's no old curr_active_slave.
   *
-  * Caller must hold bond->lock for read and curr_slave_lock for write_bh.
+  * Caller must hold curr_slave_lock for write_bh.
   */
  void bond_select_active_slave(struct bonding *bond)
  {
@@@ -1589,16 -1528,20 +1528,20 @@@ int bond_enslave(struct net_device *bon
                goto err_unregister;
        }
  
+       res = bond_sysfs_slave_add(new_slave);
+       if (res) {
+               pr_debug("Error %d calling bond_sysfs_slave_add\n", res);
+               goto err_upper_unlink;
+       }
        bond->slave_cnt++;
        bond_compute_features(bond);
        bond_set_carrier(bond);
  
        if (USES_PRIMARY(bond->params.mode)) {
-               read_lock(&bond->lock);
                write_lock_bh(&bond->curr_slave_lock);
                bond_select_active_slave(bond);
                write_unlock_bh(&bond->curr_slave_lock);
-               read_unlock(&bond->lock);
        }
  
        pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
        return 0;
  
  /* Undo stages on error */
+ err_upper_unlink:
+       bond_upper_dev_unlink(bond_dev, slave_dev);
  err_unregister:
        netdev_rx_handler_unregister(slave_dev);
  
@@@ -1618,19 -1564,13 +1564,13 @@@ err_detach
                bond_hw_addr_flush(bond_dev, slave_dev);
  
        vlan_vids_del_by_dev(slave_dev, bond_dev);
-       write_lock_bh(&bond->lock);
        if (bond->primary_slave == new_slave)
                bond->primary_slave = NULL;
        if (bond->curr_active_slave == new_slave) {
-               bond_change_active_slave(bond, NULL);
-               write_unlock_bh(&bond->lock);
-               read_lock(&bond->lock);
                write_lock_bh(&bond->curr_slave_lock);
+               bond_change_active_slave(bond, NULL);
                bond_select_active_slave(bond);
                write_unlock_bh(&bond->curr_slave_lock);
-               read_unlock(&bond->lock);
-       } else {
-               write_unlock_bh(&bond->lock);
        }
        slave_disable_netpoll(new_slave);
  
@@@ -1658,7 -1598,7 +1598,7 @@@ err_free
  err_undo_flags:
        /* Enslave of first slave has failed and we need to fix master's mac */
        if (!bond_has_slaves(bond) &&
-           ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr))
+           ether_addr_equal_64bits(bond_dev->dev_addr, slave_dev->dev_addr))
                eth_hw_addr_random(bond_dev);
  
        return res;
@@@ -1695,23 -1635,21 +1635,21 @@@ static int __bond_release_one(struct ne
        }
  
        block_netpoll_tx();
-       write_lock_bh(&bond->lock);
  
        slave = bond_get_slave_by_dev(bond, slave_dev);
        if (!slave) {
                /* not a slave of this bond */
                pr_info("%s: %s not enslaved\n",
                        bond_dev->name, slave_dev->name);
-               write_unlock_bh(&bond->lock);
                unblock_netpoll_tx();
                return -EINVAL;
        }
  
-       write_unlock_bh(&bond->lock);
        /* release the slave from its bond */
        bond->slave_cnt--;
  
+       bond_sysfs_slave_del(slave);
        bond_upper_dev_unlink(bond_dev, slave_dev);
        /* unregister rx_handler early so bond_handle_frame wouldn't be called
         * for this slave anymore.
        write_lock_bh(&bond->lock);
  
        /* Inform AD package of unbinding of slave. */
-       if (bond->params.mode == BOND_MODE_8023AD) {
-               /* must be called before the slave is
-                * detached from the list
-                */
+       if (bond->params.mode == BOND_MODE_8023AD)
                bond_3ad_unbind_slave(slave);
-       }
+       write_unlock_bh(&bond->lock);
  
        pr_info("%s: releasing %s interface %s\n",
                bond_dev->name,
        bond->current_arp_slave = NULL;
  
        if (!all && !bond->params.fail_over_mac) {
-               if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) &&
+               if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) &&
                    bond_has_slaves(bond))
                        pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n",
                                   bond_dev->name, slave_dev->name,
        if (bond->primary_slave == slave)
                bond->primary_slave = NULL;
  
-       if (oldcurrent == slave)
+       if (oldcurrent == slave) {
+               write_lock_bh(&bond->curr_slave_lock);
                bond_change_active_slave(bond, NULL);
+               write_unlock_bh(&bond->curr_slave_lock);
+       }
  
        if (bond_is_lb(bond)) {
                /* Must be called only after the slave has been
                 * has been cleared (if our_slave == old_current),
                 * but before a new active slave is selected.
                 */
-               write_unlock_bh(&bond->lock);
                bond_alb_deinit_slave(bond, slave);
-               write_lock_bh(&bond->lock);
        }
  
        if (all) {
 -              rcu_assign_pointer(bond->curr_active_slave, NULL);
 +              RCU_INIT_POINTER(bond->curr_active_slave, NULL);
        } else if (oldcurrent == slave) {
                /*
                 * Note that we hold RTNL over this sequence, so there
                 * is no concern that another slave add/remove event
                 * will interfere.
                 */
-               write_unlock_bh(&bond->lock);
-               read_lock(&bond->lock);
                write_lock_bh(&bond->curr_slave_lock);
  
                bond_select_active_slave(bond);
  
                write_unlock_bh(&bond->curr_slave_lock);
-               read_unlock(&bond->lock);
-               write_lock_bh(&bond->lock);
        }
  
        if (!bond_has_slaves(bond)) {
                }
        }
  
-       write_unlock_bh(&bond->lock);
        unblock_netpoll_tx();
        synchronize_rcu();
  
@@@ -1928,7 -1860,7 +1860,7 @@@ static int bond_miimon_inspect(struct b
  
        ignore_updelay = !bond->curr_active_slave ? true : false;
  
-       bond_for_each_slave(bond, slave, iter) {
+       bond_for_each_slave_rcu(bond, slave, iter) {
                slave->new_link = BOND_LINK_NOCHANGE;
  
                link_state = bond_check_dev_link(bond, slave->dev, 0);
@@@ -2119,48 -2051,42 +2051,42 @@@ do_failover
   * an acquisition of appropriate locks followed by a commit phase to
   * implement whatever link state changes are indicated.
   */
- void bond_mii_monitor(struct work_struct *work)
static void bond_mii_monitor(struct work_struct *work)
  {
        struct bonding *bond = container_of(work, struct bonding,
                                            mii_work.work);
        bool should_notify_peers = false;
        unsigned long delay;
  
-       read_lock(&bond->lock);
        delay = msecs_to_jiffies(bond->params.miimon);
  
        if (!bond_has_slaves(bond))
                goto re_arm;
  
+       rcu_read_lock();
        should_notify_peers = bond_should_notify_peers(bond);
  
        if (bond_miimon_inspect(bond)) {
-               read_unlock(&bond->lock);
+               rcu_read_unlock();
  
                /* Race avoidance with bond_close cancel of workqueue */
                if (!rtnl_trylock()) {
-                       read_lock(&bond->lock);
                        delay = 1;
                        should_notify_peers = false;
                        goto re_arm;
                }
  
-               read_lock(&bond->lock);
                bond_miimon_commit(bond);
  
-               read_unlock(&bond->lock);
                rtnl_unlock();  /* might sleep, hold no other locks */
-               read_lock(&bond->lock);
-       }
+       } else
+               rcu_read_unlock();
  
  re_arm:
        if (bond->params.miimon)
                queue_delayed_work(bond->wq, &bond->mii_work, delay);
  
-       read_unlock(&bond->lock);
        if (should_notify_peers) {
                if (!rtnl_trylock())
                        return;
@@@ -2414,7 -2340,7 +2340,7 @@@ static bool bond_time_in_interval(struc
   * arp is transmitted to generate traffic. see activebackup_arp_monitor for
   * arp monitoring in active backup mode.
   */
- void bond_loadbalance_arp_mon(struct work_struct *work)
static void bond_loadbalance_arp_mon(struct work_struct *work)
  {
        struct bonding *bond = container_of(work, struct bonding,
                                            arp_work.work);
        struct list_head *iter;
        int do_failover = 0;
  
-       read_lock(&bond->lock);
        if (!bond_has_slaves(bond))
                goto re_arm;
  
-       oldcurrent = bond->curr_active_slave;
+       rcu_read_lock();
+       oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
        /* see if any of the previous devices are up now (i.e. they have
         * xmt and rcv traffic). the curr_active_slave does not come into
         * the picture unless it is null. also, slave->jiffies is not needed
         * TODO: what about up/down delay in arp mode? it wasn't here before
         *       so it can wait
         */
-       bond_for_each_slave(bond, slave, iter) {
+       bond_for_each_slave_rcu(bond, slave, iter) {
                unsigned long trans_start = dev_trans_start(slave->dev);
  
                if (slave->link != BOND_LINK_UP) {
                        bond_arp_send_all(bond, slave);
        }
  
+       rcu_read_unlock();
        if (do_failover) {
+               /* the bond_select_active_slave must hold RTNL
+                * and curr_slave_lock for write.
+                */
+               if (!rtnl_trylock())
+                       goto re_arm;
                block_netpoll_tx();
                write_lock_bh(&bond->curr_slave_lock);
  
  
                write_unlock_bh(&bond->curr_slave_lock);
                unblock_netpoll_tx();
+               rtnl_unlock();
        }
  
  re_arm:
        if (bond->params.arp_interval)
                queue_delayed_work(bond->wq, &bond->arp_work,
                                   msecs_to_jiffies(bond->params.arp_interval));
-       read_unlock(&bond->lock);
  }
  
  /*
   * place for the slave.  Returns 0 if no changes are found, >0 if changes
   * to link states must be committed.
   *
-  * Called with bond->lock held for read.
+  * Called with rcu_read_lock hold.
   */
  static int bond_ab_arp_inspect(struct bonding *bond)
  {
        struct slave *slave;
        int commit = 0;
  
-       bond_for_each_slave(bond, slave, iter) {
+       bond_for_each_slave_rcu(bond, slave, iter) {
                slave->new_link = BOND_LINK_NOCHANGE;
                last_rx = slave_last_rx(bond, slave);
  
   * Called to commit link state changes noted by inspection step of
   * active-backup mode ARP monitor.
   *
-  * Called with RTNL and bond->lock for read.
+  * Called with RTNL hold.
   */
  static void bond_ab_arp_commit(struct bonding *bond)
  {
@@@ -2668,19 -2600,20 +2600,20 @@@ do_failover
  /*
   * Send ARP probes for active-backup mode ARP monitor.
   *
-  * Called with bond->lock held for read.
+  * Called with rcu_read_lock hold.
   */
  static void bond_ab_arp_probe(struct bonding *bond)
  {
-       struct slave *slave, *before = NULL, *new_slave = NULL;
+       struct slave *slave, *before = NULL, *new_slave = NULL,
+                    *curr_arp_slave = rcu_dereference(bond->current_arp_slave);
        struct list_head *iter;
        bool found = false;
  
        read_lock(&bond->curr_slave_lock);
  
-       if (bond->current_arp_slave && bond->curr_active_slave)
+       if (curr_arp_slave && bond->curr_active_slave)
                pr_info("PROBE: c_arp %s && cas %s BAD\n",
-                       bond->current_arp_slave->dev->name,
+                       curr_arp_slave->dev->name,
                        bond->curr_active_slave->dev->name);
  
        if (bond->curr_active_slave) {
         * for becoming the curr_active_slave
         */
  
-       if (!bond->current_arp_slave) {
-               bond->current_arp_slave = bond_first_slave(bond);
-               if (!bond->current_arp_slave)
+       if (!curr_arp_slave) {
+               curr_arp_slave = bond_first_slave_rcu(bond);
+               if (!curr_arp_slave)
                        return;
        }
  
-       bond_set_slave_inactive_flags(bond->current_arp_slave);
+       bond_set_slave_inactive_flags(curr_arp_slave);
  
-       bond_for_each_slave(bond, slave, iter) {
+       bond_for_each_slave_rcu(bond, slave, iter) {
                if (!found && !before && IS_UP(slave->dev))
                        before = slave;
  
                        pr_info("%s: backup interface %s is now down.\n",
                                bond->dev->name, slave->dev->name);
                }
-               if (slave == bond->current_arp_slave)
+               if (slave == curr_arp_slave)
                        found = true;
        }
  
        bond_set_slave_active_flags(new_slave);
        bond_arp_send_all(bond, new_slave);
        new_slave->jiffies = jiffies;
-       bond->current_arp_slave = new_slave;
+       rcu_assign_pointer(bond->current_arp_slave, new_slave);
  }
  
- void bond_activebackup_arp_mon(struct work_struct *work)
static void bond_activebackup_arp_mon(struct work_struct *work)
  {
        struct bonding *bond = container_of(work, struct bonding,
                                            arp_work.work);
        bool should_notify_peers = false;
        int delta_in_ticks;
  
-       read_lock(&bond->lock);
        delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
  
        if (!bond_has_slaves(bond))
                goto re_arm;
  
+       rcu_read_lock();
        should_notify_peers = bond_should_notify_peers(bond);
  
        if (bond_ab_arp_inspect(bond)) {
-               read_unlock(&bond->lock);
+               rcu_read_unlock();
  
                /* Race avoidance with bond_close flush of workqueue */
                if (!rtnl_trylock()) {
-                       read_lock(&bond->lock);
                        delta_in_ticks = 1;
                        should_notify_peers = false;
                        goto re_arm;
                }
  
-               read_lock(&bond->lock);
                bond_ab_arp_commit(bond);
  
-               read_unlock(&bond->lock);
                rtnl_unlock();
-               read_lock(&bond->lock);
+               rcu_read_lock();
        }
  
        bond_ab_arp_probe(bond);
+       rcu_read_unlock();
  
  re_arm:
        if (bond->params.arp_interval)
                queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
  
-       read_unlock(&bond->lock);
        if (should_notify_peers) {
                if (!rtnl_trylock())
                        return;
@@@ -2896,9 -2823,27 +2823,27 @@@ static int bond_slave_netdev_event(unsi
                 */
                break;
        case NETDEV_CHANGENAME:
-               /*
-                * TODO: handle changing the primary's name
-                */
+               /* we don't care if we don't have primary set */
+               if (!USES_PRIMARY(bond->params.mode) ||
+                   !bond->params.primary[0])
+                       break;
+               if (slave == bond->primary_slave) {
+                       /* slave's name changed - he's no longer primary */
+                       bond->primary_slave = NULL;
+               } else if (!strcmp(slave_dev->name, bond->params.primary)) {
+                       /* we have a new primary slave */
+                       bond->primary_slave = slave;
+               } else { /* we didn't change primary - exit */
+                       break;
+               }
+               pr_info("%s: Primary slave changed to %s, reselecting active slave.\n",
+                       bond->dev->name, bond->primary_slave ? slave_dev->name :
+                                                              "none");
+               write_lock_bh(&bond->curr_slave_lock);
+               bond_select_active_slave(bond);
+               write_unlock_bh(&bond->curr_slave_lock);
                break;
        case NETDEV_FEAT_CHANGE:
                bond_compute_features(bond);
@@@ -3178,6 -3123,7 +3123,7 @@@ static int bond_do_ioctl(struct net_dev
        struct ifslave k_sinfo;
        struct ifslave __user *u_sinfo = NULL;
        struct mii_ioctl_data *mii = NULL;
+       struct bond_opt_value newval;
        struct net *net;
        int res = 0;
  
        if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                return -EPERM;
  
-       slave_dev = dev_get_by_name(net, ifr->ifr_slave);
+       slave_dev = __dev_get_by_name(net, ifr->ifr_slave);
  
        pr_debug("slave_dev=%p:\n", slave_dev);
  
        if (!slave_dev)
-               res = -ENODEV;
-       else {
-               pr_debug("slave_dev->name=%s:\n", slave_dev->name);
-               switch (cmd) {
-               case BOND_ENSLAVE_OLD:
-               case SIOCBONDENSLAVE:
-                       res = bond_enslave(bond_dev, slave_dev);
-                       break;
-               case BOND_RELEASE_OLD:
-               case SIOCBONDRELEASE:
-                       res = bond_release(bond_dev, slave_dev);
-                       break;
-               case BOND_SETHWADDR_OLD:
-               case SIOCBONDSETHWADDR:
-                       bond_set_dev_addr(bond_dev, slave_dev);
-                       res = 0;
-                       break;
-               case BOND_CHANGE_ACTIVE_OLD:
-               case SIOCBONDCHANGEACTIVE:
-                       res = bond_option_active_slave_set(bond, slave_dev);
-                       break;
-               default:
-                       res = -EOPNOTSUPP;
-               }
+               return -ENODEV;
  
-               dev_put(slave_dev);
+       pr_debug("slave_dev->name=%s:\n", slave_dev->name);
+       switch (cmd) {
+       case BOND_ENSLAVE_OLD:
+       case SIOCBONDENSLAVE:
+               res = bond_enslave(bond_dev, slave_dev);
+               break;
+       case BOND_RELEASE_OLD:
+       case SIOCBONDRELEASE:
+               res = bond_release(bond_dev, slave_dev);
+               break;
+       case BOND_SETHWADDR_OLD:
+       case SIOCBONDSETHWADDR:
+               bond_set_dev_addr(bond_dev, slave_dev);
+               res = 0;
+               break;
+       case BOND_CHANGE_ACTIVE_OLD:
+       case SIOCBONDCHANGEACTIVE:
+               bond_opt_initstr(&newval, slave_dev->name);
+               res = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval);
+               break;
+       default:
+               res = -EOPNOTSUPP;
        }
  
        return res;
@@@ -3550,7 -3494,7 +3494,7 @@@ unwind
   * it fails, it tries to find the first available slave for transmission.
   * The skb is consumed in all cases, thus the function is void.
   */
- void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
  {
        struct list_head *iter;
        struct slave *slave;
   */
  static u32 bond_rr_gen_slave_id(struct bonding *bond)
  {
-       int packets_per_slave = bond->params.packets_per_slave;
        u32 slave_id;
+       struct reciprocal_value reciprocal_packets_per_slave;
+       int packets_per_slave = bond->params.packets_per_slave;
  
        switch (packets_per_slave) {
        case 0:
                slave_id = bond->rr_tx_counter;
                break;
        default:
+               reciprocal_packets_per_slave =
+                       bond->params.reciprocal_packets_per_slave;
                slave_id = reciprocal_divide(bond->rr_tx_counter,
-                                            packets_per_slave);
+                                            reciprocal_packets_per_slave);
                break;
        }
        bond->rr_tx_counter++;
@@@ -3707,28 -3654,24 +3654,24 @@@ static inline int bond_slave_override(s
                                      struct sk_buff *skb)
  {
        struct slave *slave = NULL;
-       struct slave *check_slave;
        struct list_head *iter;
-       int res = 1;
  
        if (!skb->queue_mapping)
                return 1;
  
        /* Find out if any slaves have the same mapping as this skb. */
-       bond_for_each_slave_rcu(bond, check_slave, iter) {
-               if (check_slave->queue_id == skb->queue_mapping) {
-                       slave = check_slave;
+       bond_for_each_slave_rcu(bond, slave, iter) {
+               if (slave->queue_id == skb->queue_mapping) {
+                       if (slave_can_tx(slave)) {
+                               bond_dev_queue_xmit(bond, skb, slave->dev);
+                               return 0;
+                       }
+                       /* If the slave isn't UP, use default transmit policy. */
                        break;
                }
        }
  
-       /* If the slave isn't UP, use default transmit policy. */
-       if (slave && slave->queue_id && IS_UP(slave->dev) &&
-           (slave->link == BOND_LINK_UP)) {
-               res = bond_dev_queue_xmit(bond, skb, slave->dev);
-       }
-       return res;
+       return 1;
  }
  
  
@@@ -3941,6 -3884,9 +3884,9 @@@ void bond_setup(struct net_device *bond
         * capable
         */
  
+       /* Don't allow bond devices to change network namespaces. */
+       bond_dev->features |= NETIF_F_NETNS_LOCAL;
        bond_dev->hw_features = BOND_VLAN_FEATURES |
                                NETIF_F_HW_VLAN_CTAG_TX |
                                NETIF_F_HW_VLAN_CTAG_RX |
@@@ -3974,6 -3920,29 +3920,29 @@@ static void bond_uninit(struct net_devi
  
  /*------------------------- Module initialization ---------------------------*/
  
+ int bond_parm_tbl_lookup(int mode, const struct bond_parm_tbl *tbl)
+ {
+       int i;
+       for (i = 0; tbl[i].modename; i++)
+               if (mode == tbl[i].mode)
+                       return tbl[i].mode;
+       return -1;
+ }
+ static int bond_parm_tbl_lookup_name(const char *modename,
+                                    const struct bond_parm_tbl *tbl)
+ {
+       int i;
+       for (i = 0; tbl[i].modename; i++)
+               if (strcmp(modename, tbl[i].modename) == 0)
+                       return tbl[i].mode;
+       return -1;
+ }
  /*
   * Convert string input module parms.  Accept either the
   * number of the mode or its string name.  A bit complicated because
   */
  int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
  {
-       int modeint = -1, i, rv;
-       char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+       int modeint;
+       char *p, modestr[BOND_MAX_MODENAME_LEN + 1];
  
        for (p = (char *)buf; *p; p++)
                if (!(isdigit(*p) || isspace(*p)))
                        break;
  
-       if (*p)
-               rv = sscanf(buf, "%20s", modestr);
-       else
-               rv = sscanf(buf, "%d", &modeint);
-       if (!rv)
-               return -1;
-       for (i = 0; tbl[i].modename; i++) {
-               if (modeint == tbl[i].mode)
-                       return tbl[i].mode;
-               if (strcmp(modestr, tbl[i].modename) == 0)
-                       return tbl[i].mode;
-       }
+       if (*p && sscanf(buf, "%20s", modestr) != 0)
+               return bond_parm_tbl_lookup_name(modestr, tbl);
+       else if (sscanf(buf, "%d", &modeint) != 0)
+               return bond_parm_tbl_lookup(modeint, tbl);
  
        return -1;
  }
  static int bond_check_params(struct bond_params *params)
  {
        int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
+       struct bond_opt_value newval, *valptr;
        int arp_all_targets_value;
  
        /*
         * Convert string parameters.
         */
        if (mode) {
-               bond_mode = bond_parse_parm(mode, bond_mode_tbl);
-               if (bond_mode == -1) {
-                       pr_err("Error: Invalid bonding mode \"%s\"\n",
-                              mode == NULL ? "NULL" : mode);
+               bond_opt_initstr(&newval, mode);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_MODE), &newval);
+               if (!valptr) {
+                       pr_err("Error: Invalid bonding mode \"%s\"\n", mode);
                        return -EINVAL;
                }
+               bond_mode = valptr->value;
        }
  
        if (xmit_hash_policy) {
                        pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
                               bond_mode_name(bond_mode));
                } else {
-                       xmit_hashtype = bond_parse_parm(xmit_hash_policy,
-                                                       xmit_hashtype_tbl);
-                       if (xmit_hashtype == -1) {
+                       bond_opt_initstr(&newval, xmit_hash_policy);
+                       valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH),
+                                               &newval);
+                       if (!valptr) {
                                pr_err("Error: Invalid xmit_hash_policy \"%s\"\n",
-                                      xmit_hash_policy == NULL ? "NULL" :
                                       xmit_hash_policy);
                                return -EINVAL;
                        }
+                       xmit_hashtype = valptr->value;
                }
        }
  
                        pr_info("lacp_rate param is irrelevant in mode %s\n",
                                bond_mode_name(bond_mode));
                } else {
-                       lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
-                       if (lacp_fast == -1) {
+                       bond_opt_initstr(&newval, lacp_rate);
+                       valptr = bond_opt_parse(bond_opt_get(BOND_OPT_LACP_RATE),
+                                               &newval);
+                       if (!valptr) {
                                pr_err("Error: Invalid lacp rate \"%s\"\n",
-                                      lacp_rate == NULL ? "NULL" : lacp_rate);
+                                      lacp_rate);
                                return -EINVAL;
                        }
+                       lacp_fast = valptr->value;
                }
        }
  
        if (ad_select) {
-               params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
-               if (params->ad_select == -1) {
-                       pr_err("Error: Invalid ad_select \"%s\"\n",
-                              ad_select == NULL ? "NULL" : ad_select);
+               bond_opt_initstr(&newval, lacp_rate);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_SELECT),
+                                       &newval);
+               if (!valptr) {
+                       pr_err("Error: Invalid ad_select \"%s\"\n", ad_select);
                        return -EINVAL;
                }
-               if (bond_mode != BOND_MODE_8023AD) {
+               params->ad_select = valptr->value;
+               if (bond_mode != BOND_MODE_8023AD)
                        pr_warning("ad_select param only affects 802.3ad mode\n");
-               }
        } else {
                params->ad_select = BOND_AD_STABLE;
        }
        }
  
        if (miimon < 0) {
-               pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to %d\n",
-                          miimon, INT_MAX, BOND_LINK_MON_INTERV);
-               miimon = BOND_LINK_MON_INTERV;
+               pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+                          miimon, INT_MAX);
+               miimon = 0;
        }
  
        if (updelay < 0) {
                num_peer_notif = 1;
        }
  
-       /* reset values for 802.3ad */
-       if (bond_mode == BOND_MODE_8023AD) {
+       /* reset values for 802.3ad/TLB/ALB */
+       if (BOND_NO_USES_ARP(bond_mode)) {
                if (!miimon) {
                        pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
                        pr_warning("Forcing miimon to 100msec\n");
                resend_igmp = BOND_DEFAULT_RESEND_IGMP;
        }
  
-       if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) {
+       bond_opt_initval(&newval, packets_per_slave);
+       if (!bond_opt_parse(bond_opt_get(BOND_OPT_PACKETS_PER_SLAVE), &newval)) {
                pr_warn("Warning: packets_per_slave (%d) should be between 0 and %u resetting to 1\n",
                        packets_per_slave, USHRT_MAX);
                packets_per_slave = 1;
        }
  
-       /* reset values for TLB/ALB */
-       if ((bond_mode == BOND_MODE_TLB) ||
-           (bond_mode == BOND_MODE_ALB)) {
-               if (!miimon) {
-                       pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n");
-                       pr_warning("Forcing miimon to 100msec\n");
-                       miimon = BOND_DEFAULT_MIIMON;
-               }
-       }
        if (bond_mode == BOND_MODE_ALB) {
                pr_notice("In ALB mode you might experience client disconnections upon reconnection of a link if the bonding module updelay parameter (%d msec) is incompatible with the forwarding delay time of the switch\n",
                          updelay);
        }
  
        if (arp_interval < 0) {
-               pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to %d\n",
-                          arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
-               arp_interval = BOND_LINK_ARP_INTERV;
+               pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to 0\n",
+                          arp_interval, INT_MAX);
+               arp_interval = 0;
        }
  
        for (arp_ip_count = 0, i = 0;
                        return -EINVAL;
                }
  
-               arp_validate_value = bond_parse_parm(arp_validate,
-                                                    arp_validate_tbl);
-               if (arp_validate_value == -1) {
+               bond_opt_initstr(&newval, arp_validate);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_VALIDATE),
+                                       &newval);
+               if (!valptr) {
                        pr_err("Error: invalid arp_validate \"%s\"\n",
-                              arp_validate == NULL ? "NULL" : arp_validate);
+                              arp_validate);
                        return -EINVAL;
                }
-       } else
+               arp_validate_value = valptr->value;
+       } else {
                arp_validate_value = 0;
+       }
  
        arp_all_targets_value = 0;
        if (arp_all_targets) {
-               arp_all_targets_value = bond_parse_parm(arp_all_targets,
-                                                       arp_all_targets_tbl);
-               if (arp_all_targets_value == -1) {
+               bond_opt_initstr(&newval, arp_all_targets);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_ALL_TARGETS),
+                                       &newval);
+               if (!valptr) {
                        pr_err("Error: invalid arp_all_targets_value \"%s\"\n",
                               arp_all_targets);
                        arp_all_targets_value = 0;
+               } else {
+                       arp_all_targets_value = valptr->value;
                }
        }
  
        if (miimon) {
                pr_info("MII link monitoring set to %d ms\n", miimon);
        } else if (arp_interval) {
+               valptr = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
+                                         arp_validate_value);
                pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):",
-                       arp_interval,
-                       arp_validate_tbl[arp_validate_value].modename,
-                       arp_ip_count);
+                       arp_interval, valptr->string, arp_ip_count);
  
                for (i = 0; i < arp_ip_count; i++)
                        pr_info(" %s", arp_ip_target[i]);
        }
  
        if (primary && primary_reselect) {
-               primary_reselect_value = bond_parse_parm(primary_reselect,
-                                                        pri_reselect_tbl);
-               if (primary_reselect_value == -1) {
+               bond_opt_initstr(&newval, primary_reselect);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_PRIMARY_RESELECT),
+                                       &newval);
+               if (!valptr) {
                        pr_err("Error: Invalid primary_reselect \"%s\"\n",
-                              primary_reselect ==
-                                       NULL ? "NULL" : primary_reselect);
+                              primary_reselect);
                        return -EINVAL;
                }
+               primary_reselect_value = valptr->value;
        } else {
                primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
        }
  
        if (fail_over_mac) {
-               fail_over_mac_value = bond_parse_parm(fail_over_mac,
-                                                     fail_over_mac_tbl);
-               if (fail_over_mac_value == -1) {
+               bond_opt_initstr(&newval, fail_over_mac);
+               valptr = bond_opt_parse(bond_opt_get(BOND_OPT_FAIL_OVER_MAC),
+                                       &newval);
+               if (!valptr) {
                        pr_err("Error: invalid fail_over_mac \"%s\"\n",
-                              arp_validate == NULL ? "NULL" : arp_validate);
+                              fail_over_mac);
                        return -EINVAL;
                }
+               fail_over_mac_value = valptr->value;
                if (bond_mode != BOND_MODE_ACTIVEBACKUP)
                        pr_warning("Warning: fail_over_mac only affects active-backup mode.\n");
        } else {
                fail_over_mac_value = BOND_FOM_NONE;
        }
  
+       if (lp_interval == 0) {
+               pr_warning("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
+                          INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
+               lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
+       }
        /* fill params struct with the proper values */
        params->mode = bond_mode;
        params->xmit_policy = xmit_hashtype;
        params->all_slaves_active = all_slaves_active;
        params->resend_igmp = resend_igmp;
        params->min_links = min_links;
-       params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
-       if (packets_per_slave > 1)
-               params->packets_per_slave = reciprocal_value(packets_per_slave);
-       else
-               params->packets_per_slave = packets_per_slave;
+       params->lp_interval = lp_interval;
+       params->packets_per_slave = packets_per_slave;
+       if (packets_per_slave > 0) {
+               params->reciprocal_packets_per_slave =
+                       reciprocal_value(packets_per_slave);
+       } else {
+               /* reciprocal_packets_per_slave is unused if
+                * packets_per_slave is 0 or 1, just initialize it
+                */
+               params->reciprocal_packets_per_slave =
+                       (struct reciprocal_value) { 0 };
+       }
        if (primary) {
                strncpy(params->primary, primary, IFNAMSIZ);
                params->primary[IFNAMSIZ - 1] = 0;
index f615fdec0f1b2fb800189d97395554ecd392fa60,d8b86c83dd15a752d45f2279c31caffe7e0ae8e8..0fe19d609c2ecbf0d84881f2f0960916eb4c010c
@@@ -66,6 -66,7 +66,7 @@@ static void hydra_block_input(struct ne
  static void hydra_block_output(struct net_device *dev, int count,
                               const unsigned char *buf, int start_page);
  static void hydra_remove_one(struct zorro_dev *z);
+ static u32 hydra_msg_enable;
  
  static struct zorro_device_id hydra_zorro_tbl[] = {
      { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
@@@ -113,12 -114,13 +114,13 @@@ static const struct net_device_ops hydr
  static int hydra_init(struct zorro_dev *z)
  {
      struct net_device *dev;
 -    unsigned long board = ZTWO_VADDR(z->resource.start);
 +    unsigned long board = (unsigned long)ZTWO_VADDR(z->resource.start);
      unsigned long ioaddr = board+HYDRA_NIC_BASE;
      const char name[] = "NE2000";
      int start_page, stop_page;
      int j;
      int err;
+     struct ei_device *ei_local;
  
      static u32 hydra_offsets[16] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
      start_page = NESM_START_PG;
      stop_page = NESM_STOP_PG;
  
+     ei_local = netdev_priv(dev);
+     ei_local->msg_enable = hydra_msg_enable;
      dev->base_addr = ioaddr;
      dev->irq = IRQ_AMIGA_PORTS;
  
@@@ -187,15 -191,16 +191,16 @@@ static int hydra_open(struct net_devic
  
  static int hydra_close(struct net_device *dev)
  {
-     if (ei_debug > 1)
-       printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
+     struct ei_device *ei_local = netdev_priv(dev);
+     netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
      __ei_close(dev);
      return 0;
  }
  
  static void hydra_reset_8390(struct net_device *dev)
  {
-     printk(KERN_INFO "Hydra hw reset not there\n");
+     netdev_info(dev, "Hydra hw reset not there\n");
  }
  
  static void hydra_get_8390_hdr(struct net_device *dev,
index ae2a12b7db62db6fcc748019af9abca0e2abf051,7b373e65f3771a940c247d18fcd28959203054fe..8308728fad0511c74f0164488a59e09ef2ea8194
@@@ -44,6 -44,8 +44,8 @@@
  static const char version[] =
        "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  
+ static u32 zorro8390_msg_enable;
  #include "lib8390.c"
  
  #define DRV_NAME      "zorro8390"
@@@ -86,9 -88,9 +88,9 @@@ static struct card_info 
  static void zorro8390_reset_8390(struct net_device *dev)
  {
        unsigned long reset_start_time = jiffies;
+       struct ei_device *ei_local = netdev_priv(dev);
  
-       if (ei_debug > 1)
-               netdev_dbg(dev, "resetting - t=%ld...\n", jiffies);
+       netif_dbg(ei_local, hw, dev, "resetting - t=%ld...\n", jiffies);
  
        z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
  
@@@ -119,8 -121,9 +121,9 @@@ static void zorro8390_get_8390_hdr(stru
         * If it does, it's the last thing you'll see
         */
        if (ei_status.dmaing) {
-               netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
-                          __func__, ei_status.dmaing, ei_status.irqlock);
+               netdev_warn(dev,
+                           "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
+                           __func__, ei_status.dmaing, ei_status.irqlock);
                return;
        }
  
@@@ -230,7 -233,7 +233,7 @@@ static void zorro8390_block_output(stru
        while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
                if (time_after(jiffies, dma_start + 2 * HZ / 100)) {
                                        /* 20ms */
-                       netdev_err(dev, "timeout waiting for Tx RDC\n");
+                       netdev_warn(dev, "timeout waiting for Tx RDC\n");
                        zorro8390_reset_8390(dev);
                        __NS8390_init(dev, 1);
                        break;
@@@ -248,8 -251,9 +251,9 @@@ static int zorro8390_open(struct net_de
  
  static int zorro8390_close(struct net_device *dev)
  {
-       if (ei_debug > 1)
-               netdev_dbg(dev, "Shutting down ethercard\n");
+       struct ei_device *ei_local = netdev_priv(dev);
+       netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard\n");
        __ei_close(dev);
        return 0;
  }
@@@ -287,12 -291,13 +291,13 @@@ static const struct net_device_ops zorr
  };
  
  static int zorro8390_init(struct net_device *dev, unsigned long board,
 -                        const char *name, unsigned long ioaddr)
 +                        const char *name, void __iomem *ioaddr)
  {
        int i;
        int err;
        unsigned char SA_prom[32];
        int start_page, stop_page;
+       struct ei_device *ei_local = netdev_priv(dev);
        static u32 zorro8390_offsets[16] = {
                0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
                0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
        start_page = NESM_START_PG;
        stop_page = NESM_STOP_PG;
  
 -      dev->base_addr = ioaddr;
 +      dev->base_addr = (unsigned long)ioaddr;
        dev->irq = IRQ_AMIGA_PORTS;
  
        /* Install the Interrupt handler */
  
        dev->netdev_ops = &zorro8390_netdev_ops;
        __NS8390_init(dev, 0);
+       ei_local->msg_enable = zorro8390_msg_enable;
        err = register_netdev(dev);
        if (err) {
                free_irq(IRQ_AMIGA_PORTS, dev);
index 4bd2d80d065e0555ae18d6c8795373912738b944,55c4ea7402586f8f2b3124f570ca6bd4246046bd..91b69ff4b4a20f8f2bd2f6c9405cf6ab60af7f6a
@@@ -134,7 -134,8 +134,8 @@@ static void dump_dev_cap_flags2(struct 
                [5] = "Time stamping support",
                [6] = "VST (control vlan insertion/stripping) support",
                [7] = "FSM (MAC anti-spoofing) support",
-               [8] = "Dynamic QP updates support"
+               [8] = "Dynamic QP updates support",
+               [9] = "TCP/IP offloads/flow-steering for VXLAN support"
        };
        int i;
  
@@@ -207,25 -208,25 +208,25 @@@ int mlx4_QUERY_FUNC_CAP_wrapper(struct 
  
  /* when opcode modifier = 1 */
  #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET               0x3
- #define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET      0x8
- #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET               0xc
+ #define QUERY_FUNC_CAP_FLAGS0_OFFSET          0x8
+ #define QUERY_FUNC_CAP_FLAGS1_OFFSET          0xc
  
  #define QUERY_FUNC_CAP_QP0_TUNNEL             0x10
  #define QUERY_FUNC_CAP_QP0_PROXY              0x14
  #define QUERY_FUNC_CAP_QP1_TUNNEL             0x18
  #define QUERY_FUNC_CAP_QP1_PROXY              0x1c
+ #define QUERY_FUNC_CAP_PHYS_PORT_ID           0x28
  
- #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC    0x40
- #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN   0x80
+ #define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC               0x40
+ #define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN      0x80
+ #define QUERY_FUNC_CAP_FLAGS1_NIC_INFO                        0x10
  
- #define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80
+ #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80
  
        if (vhcr->op_modifier == 1) {
-               field = 0;
-               /* ensure force vlan and force mac bits are not set */
-               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
-               /* ensure that phy_wqe_gid bit is not set */
-               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
+               /* Set nic_info bit to mark new fields support */
+               field  = QUERY_FUNC_CAP_FLAGS1_NIC_INFO;
+               MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET);
  
                field = vhcr->in_modifier; /* phys-port = logical-port */
                MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
                size += 2;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY);
  
+               MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier],
+                        QUERY_FUNC_CAP_PHYS_PORT_ID);
        } else if (vhcr->op_modifier == 0) {
                /* enable rdma and ethernet interfaces, and new quota locations */
                field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA |
@@@ -391,22 -395,22 +395,22 @@@ int mlx4_QUERY_FUNC_CAP(struct mlx4_de
                goto out;
        }
  
+       MLX4_GET(func_cap->flags1, outbox, QUERY_FUNC_CAP_FLAGS1_OFFSET);
        if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_ETH) {
-               MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET);
-               if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) {
+               if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_OFFSET) {
                        mlx4_err(dev, "VLAN is enforced on this port\n");
                        err = -EPROTONOSUPPORT;
                        goto out;
                }
  
-               if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) {
+               if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_MAC) {
                        mlx4_err(dev, "Force mac is enabled on this port\n");
                        err = -EPROTONOSUPPORT;
                        goto out;
                }
        } else if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_IB) {
-               MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET);
-               if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) {
+               MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET);
+               if (field & QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID) {
                        mlx4_err(dev, "phy_wqe_gid is "
                                 "enforced on this ib port\n");
                        err = -EPROTONOSUPPORT;
        MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_PROXY);
        func_cap->qp1_proxy_qpn = size & 0xFFFFFF;
  
+       if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_NIC_INFO)
+               MLX4_GET(func_cap->phys_port_id, outbox,
+                        QUERY_FUNC_CAP_PHYS_PORT_ID);
        /* All other resources are allocated by the master, but we still report
         * 'num' and 'reserved' capabilities as follows:
         * - num remains the maximum resource index
@@@ -513,7 -521,6 +521,7 @@@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev 
  #define QUERY_DEV_CAP_MAX_XRC_OFFSET          0x67
  #define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET     0x68
  #define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET      0x70
 +#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET      0x74
  #define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET   0x76
  #define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET     0x77
  #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET  0x80
  #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET                0x98
  #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET               0xa0
  #define QUERY_DEV_CAP_FW_REASSIGN_MAC         0x9d
+ #define QUERY_DEV_CAP_VXLAN                   0x9e
  
        dev_cap->flags2 = 0;
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (field & 0x80)
                dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN;
        dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f;
 +      MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
 +      if (field & 0x80)
 +              dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB;
        MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET);
        dev_cap->fs_max_num_qp_per_entry = field;
        MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC);
        if (field & 1<<6)
                dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN;
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
+       if (field & 1<<3)
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS;
        MLX4_GET(dev_cap->max_icm_sz, outbox,
                 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
        if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS)
@@@ -846,6 -854,11 +858,11 @@@ int mlx4_QUERY_DEV_CAP_wrapper(struct m
        field &= 0x7f;
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
  
+       /* For guests, disable vxlan tunneling */
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
+       field &= 0xf7;
+       MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN);
        /* For guests, report Blueflame disabled */
        MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET);
        field &= 0x7f;
                MLX4_PUT(outbox->buf, field,
                         QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
        }
 +
 +      /* turn off ipoib managed steering for guests */
 +      MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
 +      field &= ~0x80;
 +      MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
 +
        return 0;
  }
  
@@@ -1277,6 -1284,7 +1294,7 @@@ int mlx4_INIT_HCA(struct mlx4_dev *dev
  #define INIT_HCA_IN_SIZE               0x200
  #define INIT_HCA_VERSION_OFFSET                0x000
  #define        INIT_HCA_VERSION                2
+ #define INIT_HCA_VXLAN_OFFSET          0x0c
  #define INIT_HCA_CACHELINE_SZ_OFFSET   0x0e
  #define INIT_HCA_FLAGS_OFFSET          0x014
  #define INIT_HCA_QPC_OFFSET            0x020
        MLX4_PUT(inbox, param->uar_page_sz,     INIT_HCA_UAR_PAGE_SZ_OFFSET);
        MLX4_PUT(inbox, param->log_uar_sz,      INIT_HCA_LOG_UAR_SZ_OFFSET);
  
+       /* set parser VXLAN attributes */
+       if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) {
+               u8 parser_params = 0;
+               MLX4_PUT(inbox, parser_params,  INIT_HCA_VXLAN_OFFSET);
+       }
        err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000,
                       MLX4_CMD_NATIVE);
  
@@@ -1723,6 -1737,43 +1747,43 @@@ int mlx4_NOP(struct mlx4_dev *dev
        return mlx4_cmd(dev, 0, 0x1f, 0, MLX4_CMD_NOP, 100, MLX4_CMD_NATIVE);
  }
  
+ int mlx4_get_phys_port_id(struct mlx4_dev *dev)
+ {
+       u8 port;
+       u32 *outbox;
+       struct mlx4_cmd_mailbox *mailbox;
+       u32 in_mod;
+       u32 guid_hi, guid_lo;
+       int err, ret = 0;
+ #define MOD_STAT_CFG_PORT_OFFSET 8
+ #define MOD_STAT_CFG_GUID_H    0X14
+ #define MOD_STAT_CFG_GUID_L    0X1c
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       outbox = mailbox->buf;
+       for (port = 1; port <= dev->caps.num_ports; port++) {
+               in_mod = port << MOD_STAT_CFG_PORT_OFFSET;
+               err = mlx4_cmd_box(dev, 0, mailbox->dma, in_mod, 0x2,
+                                  MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A,
+                                  MLX4_CMD_NATIVE);
+               if (err) {
+                       mlx4_err(dev, "Fail to get port %d uplink guid\n",
+                                port);
+                       ret = err;
+               } else {
+                       MLX4_GET(guid_hi, outbox, MOD_STAT_CFG_GUID_H);
+                       MLX4_GET(guid_lo, outbox, MOD_STAT_CFG_GUID_L);
+                       dev->caps.phys_port_id[port] = (u64)guid_lo |
+                                                      (u64)guid_hi << 32;
+               }
+       }
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return ret;
+ }
  #define MLX4_WOL_SETUP_MODE (5 << 28)
  int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port)
  {
index 34dffcf61bffb2114a82b7281e9c2e840a92dcac,aefb74f56344bd479492ccf0bae47f727540ff7e..db7dc0b6667d6f1ecb57076db2e855bd7a9cb448
@@@ -125,9 -125,14 +125,14 @@@ static struct mlx4_promisc_qp *get_prom
                                              enum mlx4_steer_type steer,
                                              u32 qpn)
  {
-       struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];
+       struct mlx4_steer *s_steer;
        struct mlx4_promisc_qp *pqp;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
        list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
                if (pqp->qpn == qpn)
                        return pqp;
@@@ -154,6 -159,9 +159,9 @@@ static int new_steering_entry(struct ml
        u32 prot;
        int err;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
        if (!new_entry)
@@@ -238,6 -246,9 +246,9 @@@ static int existing_steering_entry(stru
        struct mlx4_promisc_qp *pqp;
        struct mlx4_promisc_qp *dqp;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
  
        pqp = get_promisc_qp(dev, port, steer, qpn);
@@@ -283,6 -294,9 +294,9 @@@ static bool check_duplicate_entry(struc
        struct mlx4_steer_index *tmp_entry, *entry = NULL;
        struct mlx4_promisc_qp *dqp, *tmp_dqp;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
  
        /* if qp is not promisc, it cannot be duplicated */
@@@ -324,6 -338,9 +338,9 @@@ static bool can_remove_steering_entry(s
        bool ret = false;
        int i;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
  
        mailbox = mlx4_alloc_cmd_mailbox(dev);
@@@ -378,6 -395,9 +395,9 @@@ static int add_promisc_qp(struct mlx4_d
        int err;
        struct mlx4_priv *priv = mlx4_priv(dev);
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
  
        mutex_lock(&priv->mcg_table.mutex);
@@@ -484,6 -504,9 +504,9 @@@ static int remove_promisc_qp(struct mlx
        int loc, i;
        int err;
  
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        mutex_lock(&priv->mcg_table.mutex);
  
@@@ -674,7 -697,8 +697,8 @@@ const u16 __sw_id_hw[] = 
        [MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
        [MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
        [MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
-       [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006
+       [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006,
+       [MLX4_NET_TRANS_RULE_ID_VXLAN]   = 0xE008
  };
  
  int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
@@@ -699,7 -723,9 +723,9 @@@ static const int __rule_hw_sz[] = 
        [MLX4_NET_TRANS_RULE_ID_TCP] =
                sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
        [MLX4_NET_TRANS_RULE_ID_UDP] =
-               sizeof(struct mlx4_net_trans_rule_hw_tcp_udp)
+               sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
+       [MLX4_NET_TRANS_RULE_ID_VXLAN] =
+               sizeof(struct mlx4_net_trans_rule_hw_vxlan)
  };
  
  int mlx4_hw_rule_sz(struct mlx4_dev *dev,
@@@ -764,6 -790,13 +790,13 @@@ static int parse_trans_rule(struct mlx4
                rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
                break;
  
+       case MLX4_NET_TRANS_RULE_ID_VXLAN:
+               rule_hw->vxlan.vni =
+                       cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
+               rule_hw->vxlan.vni_mask =
+                       cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
+               break;
        default:
                return -EINVAL;
        }
@@@ -895,23 -928,6 +928,23 @@@ int mlx4_flow_detach(struct mlx4_dev *d
  }
  EXPORT_SYMBOL_GPL(mlx4_flow_detach);
  
 +int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
 +                                    u32 max_range_qpn)
 +{
 +      int err;
 +      u64 in_param;
 +
 +      in_param = ((u64) min_range_qpn) << 32;
 +      in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF;
 +
 +      err = mlx4_cmd(dev, in_param, 0, 0,
 +                      MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
 +                      MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
 +
 +      return err;
 +}
 +EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE);
 +
  int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                          int block_mcast_loopback, enum mlx4_protocol prot,
                          enum mlx4_steer_type steer)
@@@ -1013,7 -1029,7 +1046,7 @@@ out
                                  index, dev->caps.num_mgms);
                else
                        mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                        index - dev->caps.num_mgms);
+                                        index - dev->caps.num_mgms, MLX4_USE_RR);
        }
        mutex_unlock(&priv->mcg_table.mutex);
  
@@@ -1104,7 -1120,7 +1137,7 @@@ int mlx4_qp_detach_common(struct mlx4_d
                                          index, amgm_index, dev->caps.num_mgms);
                        else
                                mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                                amgm_index - dev->caps.num_mgms);
+                                                amgm_index - dev->caps.num_mgms, MLX4_USE_RR);
                }
        } else {
                /* Remove entry from AMGM */
                                  prev, index, dev->caps.num_mgms);
                else
                        mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                        index - dev->caps.num_mgms);
+                                        index - dev->caps.num_mgms, MLX4_USE_RR);
        }
  
  out:
index 59f67f9086dc38567dbc0c1992a7c67245a0773e,6ed9dfa5f05bcbba11a8047d9e165f94fce7d86c..6b65f77952153f5dd1ceab2d074e456b2a9567c4
@@@ -783,6 -783,11 +783,11 @@@ enum 
        MLX4_PCI_DEV_FORCE_SENSE_PORT   = 1 << 1,
  };
  
+ enum {
+       MLX4_NO_RR      = 0,
+       MLX4_USE_RR     = 1,
+ };
  struct mlx4_priv {
        struct mlx4_dev         dev;
  
@@@ -844,9 -849,10 +849,10 @@@ static inline struct mlx4_priv *mlx4_pr
  extern struct workqueue_struct *mlx4_wq;
  
  u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
- void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
+ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj, int use_rr);
  u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
- void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt);
+ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt,
+                           int use_rr);
  u32 mlx4_bitmap_avail(struct mlx4_bitmap *bitmap);
  int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
                     u32 reserved_bot, u32 resetrved_top);
@@@ -1236,11 -1242,6 +1242,11 @@@ int mlx4_QP_FLOW_STEERING_DETACH_wrappe
                                         struct mlx4_cmd_mailbox *inbox,
                                         struct mlx4_cmd_mailbox *outbox,
                                         struct mlx4_cmd_info *cmd);
 +int mlx4_FLOW_STEERING_IB_UC_QP_RANGE_wrapper(struct mlx4_dev *dev, int slave,
 +                                            struct mlx4_vhcr *vhcr,
 +                                            struct mlx4_cmd_mailbox *inbox,
 +                                            struct mlx4_cmd_mailbox *outbox,
 +                                            struct mlx4_cmd_info *cmd);
  
  int mlx4_get_mgm_entry_size(struct mlx4_dev *dev);
  int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
index f50ef6a5ee5e47ecf495ea8b6210ce9ae7635bb3,93f75ec78c8224b36822103aafb4f15c437119e3..a58bcbf1b8067e88e5e153f25cd285ef57b90bb3
@@@ -123,26 -123,6 +123,26 @@@ static int mlx4_set_port_mac_table(stru
        return err;
  }
  
 +int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx)
 +{
 +      struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
 +      struct mlx4_mac_table *table = &info->mac_table;
 +      int i;
 +
 +      for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
 +              if (!table->refs[i])
 +                      continue;
 +
 +              if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
 +                      *idx = i;
 +                      return 0;
 +              }
 +      }
 +
 +      return -ENOENT;
 +}
 +EXPORT_SYMBOL_GPL(mlx4_find_cached_mac);
 +
  int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
  {
        struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
@@@ -820,6 -800,47 +820,47 @@@ int mlx4_SET_PORT_SCHEDULER(struct mlx4
  }
  EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER);
  
+ enum {
+       VXLAN_ENABLE_MODIFY     = 1 << 7,
+       VXLAN_STEERING_MODIFY   = 1 << 6,
+       VXLAN_ENABLE            = 1 << 7,
+ };
+ struct mlx4_set_port_vxlan_context {
+       u32     reserved1;
+       u8      modify_flags;
+       u8      reserved2;
+       u8      enable_flags;
+       u8      steering;
+ };
+ int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering)
+ {
+       int err;
+       u32 in_mod;
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_port_vxlan_context  *context;
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       context = mailbox->buf;
+       memset(context, 0, sizeof(*context));
+       context->modify_flags = VXLAN_ENABLE_MODIFY | VXLAN_STEERING_MODIFY;
+       context->enable_flags = VXLAN_ENABLE;
+       context->steering  = steering;
+       in_mod = MLX4_SET_PORT_VXLAN << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+ }
+ EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN);
  int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
                                struct mlx4_vhcr *vhcr,
                                struct mlx4_cmd_mailbox *inbox,
index 663510325c22421cb8958f33238dc7ed7c60bd42,734423d847c87fd6a6c2b4c6f0c0a2be525e1921..57428a0cb9ddc37fd226cb22305323185eda22fd
@@@ -1340,43 -1340,29 +1340,29 @@@ static int cq_res_start_move_to(struct 
  
        spin_lock_irq(mlx4_tlock(dev));
        r = res_tracker_lookup(&tracker->res_tree[RES_CQ], cqn);
-       if (!r)
+       if (!r) {
                err = -ENOENT;
-       else if (r->com.owner != slave)
+       } else if (r->com.owner != slave) {
                err = -EPERM;
-       else {
-               switch (state) {
-               case RES_CQ_BUSY:
-                       err = -EBUSY;
-                       break;
-               case RES_CQ_ALLOCATED:
-                       if (r->com.state != RES_CQ_HW)
-                               err = -EINVAL;
-                       else if (atomic_read(&r->ref_count))
-                               err = -EBUSY;
-                       else
-                               err = 0;
-                       break;
-               case RES_CQ_HW:
-                       if (r->com.state != RES_CQ_ALLOCATED)
-                               err = -EINVAL;
-                       else
-                               err = 0;
-                       break;
-               default:
+       } else if (state == RES_CQ_ALLOCATED) {
+               if (r->com.state != RES_CQ_HW)
                        err = -EINVAL;
-               }
+               else if (atomic_read(&r->ref_count))
+                       err = -EBUSY;
+               else
+                       err = 0;
+       } else if (state != RES_CQ_HW || r->com.state != RES_CQ_ALLOCATED) {
+               err = -EINVAL;
+       } else {
+               err = 0;
+       }
  
-               if (!err) {
-                       r->com.from_state = r->com.state;
-                       r->com.to_state = state;
-                       r->com.state = RES_CQ_BUSY;
-                       if (cq)
-                               *cq = r;
-               }
+       if (!err) {
+               r->com.from_state = r->com.state;
+               r->com.to_state = state;
+               r->com.state = RES_CQ_BUSY;
+               if (cq)
+                       *cq = r;
        }
  
        spin_unlock_irq(mlx4_tlock(dev));
  }
  
  static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
-                                enum res_cq_states state, struct res_srq **srq)
+                                enum res_srq_states state, struct res_srq **srq)
  {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
  
        spin_lock_irq(mlx4_tlock(dev));
        r = res_tracker_lookup(&tracker->res_tree[RES_SRQ], index);
-       if (!r)
+       if (!r) {
                err = -ENOENT;
-       else if (r->com.owner != slave)
+       } else if (r->com.owner != slave) {
                err = -EPERM;
-       else {
-               switch (state) {
-               case RES_SRQ_BUSY:
-                       err = -EINVAL;
-                       break;
-               case RES_SRQ_ALLOCATED:
-                       if (r->com.state != RES_SRQ_HW)
-                               err = -EINVAL;
-                       else if (atomic_read(&r->ref_count))
-                               err = -EBUSY;
-                       break;
-               case RES_SRQ_HW:
-                       if (r->com.state != RES_SRQ_ALLOCATED)
-                               err = -EINVAL;
-                       break;
-               default:
+       } else if (state == RES_SRQ_ALLOCATED) {
+               if (r->com.state != RES_SRQ_HW)
                        err = -EINVAL;
-               }
+               else if (atomic_read(&r->ref_count))
+                       err = -EBUSY;
+       } else if (state != RES_SRQ_HW || r->com.state != RES_SRQ_ALLOCATED) {
+               err = -EINVAL;
+       }
  
-               if (!err) {
-                       r->com.from_state = r->com.state;
-                       r->com.to_state = state;
-                       r->com.state = RES_SRQ_BUSY;
-                       if (srq)
-                               *srq = r;
-               }
+       if (!err) {
+               r->com.from_state = r->com.state;
+               r->com.to_state = state;
+               r->com.state = RES_SRQ_BUSY;
+               if (srq)
+                       *srq = r;
        }
  
        spin_unlock_irq(mlx4_tlock(dev));
@@@ -3634,7 -3606,7 +3606,7 @@@ static int validate_eth_header_mac(int 
            !is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
                list_for_each_entry_safe(res, tmp, rlist, list) {
                        be_mac = cpu_to_be64(res->mac << 16);
-                       if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN))
+                       if (ether_addr_equal((u8 *)&be_mac, eth_header->eth.dst_mac))
                                return 0;
                }
                pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n",
@@@ -3844,16 -3816,6 +3816,16 @@@ int mlx4_QUERY_IF_STAT_wrapper(struct m
        return err;
  }
  
 +int mlx4_FLOW_STEERING_IB_UC_QP_RANGE_wrapper(struct mlx4_dev *dev, int slave,
 +                                            struct mlx4_vhcr *vhcr,
 +                                            struct mlx4_cmd_mailbox *inbox,
 +                                            struct mlx4_cmd_mailbox *outbox,
 +                                            struct mlx4_cmd_info *cmd)
 +{
 +      return -EPERM;
 +}
 +
 +
  static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
  {
        struct res_gid *rgid;
index 04b3ec1352f1eb9f532f7a6ab770615441f023fd,da5a1b0db3c89de86f23f73bdb6bdf41247b50dc..9e4ddbba70363b8fdedf412b6c830a44f1a0f045
@@@ -37,7 -37,6 +37,6 @@@
  #include <linux/fcntl.h>
  #include <linux/gfp.h>
  #include <linux/interrupt.h>
- #include <linux/init.h>
  #include <linux/ioport.h>
  #include <linux/in.h>
  #include <linux/string.h>
@@@ -52,6 -51,7 +51,6 @@@
  #include <linux/bitrev.h>
  #include <linux/slab.h>
  
 -#include <asm/bootinfo.h>
  #include <asm/pgtable.h>
  #include <asm/io.h>
  #include <asm/hwtest.h>
index f51204cfe12fb1e08c730683c7f5d0747ca1156d,8e3477058b9b415f5f1b9528c077ddaeb5def117..b2fe9bb89633e289837f295367ab408840d404be
@@@ -49,7 -49,6 +49,6 @@@
  #include <linux/pci.h>
  #include <linux/delay.h>
  #include <linux/hdlc.h>
- #include <linux/init.h>
  #include <linux/in.h>
  #include <linux/if_arp.h>
  #include <linux/netdevice.h>
@@@ -973,7 -972,6 +972,6 @@@ static int lmc_init_one(struct pci_dev 
      return 0;
  
  err_hdlcdev:
-       pci_set_drvdata(pdev, NULL);
        kfree(sc);
  err_kzalloc:
        pci_release_regions(pdev);
@@@ -995,7 -993,6 +993,6 @@@ static void lmc_remove_one(struct pci_d
                free_netdev(dev);
                pci_release_regions(pdev);
                pci_disable_device(pdev);
-               pci_set_drvdata(pdev, NULL);
        }
  }
  
@@@ -2126,7 -2123,7 +2123,7 @@@ bug_out
  
      spin_unlock_irqrestore(&sc->lmc_lock, flags);
  
 -    lmc_trace(dev, "lmc_driver_timout out");
 +    lmc_trace(dev, "lmc_driver_timeout out");
  
  
  }
index 2ab82fe75edeeb6192c5088408082c8f0318e10f,d7bee8a5308e6cf2b54eaf20a611bea3f48490e0..e955c569298626c924f6cec16c3d32de8bec54d6
@@@ -617,7 -617,9 +617,9 @@@ static int xennet_start_xmit(struct sk_
                tx->flags |= XEN_NETTXF_extra_info;
  
                gso->u.gso.size = skb_shinfo(skb)->gso_size;
-               gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
+               gso->u.gso.type = (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) ?
+                       XEN_NETIF_GSO_TYPE_TCPV6 :
+                       XEN_NETIF_GSO_TYPE_TCPV4;
                gso->u.gso.pad = 0;
                gso->u.gso.features = 0;
  
@@@ -809,15 -811,18 +811,18 @@@ static int xennet_set_skb_gso(struct sk
                return -EINVAL;
        }
  
-       /* Currently only TCPv4 S.O. is supported. */
-       if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
+       if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4 &&
+           gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV6) {
                if (net_ratelimit())
                        pr_warn("Bad GSO type %d\n", gso->u.gso.type);
                return -EINVAL;
        }
  
        skb_shinfo(skb)->gso_size = gso->u.gso.size;
-       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+       skb_shinfo(skb)->gso_type =
+               (gso->u.gso.type == XEN_NETIF_GSO_TYPE_TCPV4) ?
+               SKB_GSO_TCPV4 :
+               SKB_GSO_TCPV6;
  
        /* Header must be checked, and gso_segs computed. */
        skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
@@@ -859,9 -864,7 +864,7 @@@ static RING_IDX xennet_fill_frags(struc
  
  static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
  {
-       struct iphdr *iph;
-       int err = -EPROTO;
-       int recalculate_partial_csum = 0;
+       bool recalculate_partial_csum = false;
  
        /*
         * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy
                struct netfront_info *np = netdev_priv(dev);
                np->rx_gso_checksum_fixup++;
                skb->ip_summed = CHECKSUM_PARTIAL;
-               recalculate_partial_csum = 1;
+               recalculate_partial_csum = true;
        }
  
        /* A non-CHECKSUM_PARTIAL SKB does not require setup. */
        if (skb->ip_summed != CHECKSUM_PARTIAL)
                return 0;
  
-       if (skb->protocol != htons(ETH_P_IP))
-               goto out;
-       iph = (void *)skb->data;
-       switch (iph->protocol) {
-       case IPPROTO_TCP:
-               if (!skb_partial_csum_set(skb, 4 * iph->ihl,
-                                         offsetof(struct tcphdr, check)))
-                       goto out;
-               if (recalculate_partial_csum) {
-                       struct tcphdr *tcph = tcp_hdr(skb);
-                       tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                                        skb->len - iph->ihl*4,
-                                                        IPPROTO_TCP, 0);
-               }
-               break;
-       case IPPROTO_UDP:
-               if (!skb_partial_csum_set(skb, 4 * iph->ihl,
-                                         offsetof(struct udphdr, check)))
-                       goto out;
-               if (recalculate_partial_csum) {
-                       struct udphdr *udph = udp_hdr(skb);
-                       udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                                        skb->len - iph->ihl*4,
-                                                        IPPROTO_UDP, 0);
-               }
-               break;
-       default:
-               if (net_ratelimit())
-                       pr_err("Attempting to checksum a non-TCP/UDP packet, dropping a protocol %d packet\n",
-                              iph->protocol);
-               goto out;
-       }
-       err = 0;
- out:
-       return err;
+       return skb_checksum_setup(skb, recalculate_partial_csum);
  }
  
  static int handle_incoming_queue(struct net_device *dev,
@@@ -1233,6 -1196,15 +1196,15 @@@ static netdev_features_t xennet_fix_fea
                        features &= ~NETIF_F_SG;
        }
  
+       if (features & NETIF_F_IPV6_CSUM) {
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                                "feature-ipv6-csum-offload", "%d", &val) < 0)
+                       val = 0;
+               if (!val)
+                       features &= ~NETIF_F_IPV6_CSUM;
+       }
        if (features & NETIF_F_TSO) {
                if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
                                 "feature-gso-tcpv4", "%d", &val) < 0)
                        features &= ~NETIF_F_TSO;
        }
  
+       if (features & NETIF_F_TSO6) {
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                                "feature-gso-tcpv6", "%d", &val) < 0)
+                       val = 0;
+               if (!val)
+                       features &= ~NETIF_F_TSO6;
+       }
        return features;
  }
  
@@@ -1380,7 -1361,9 +1361,9 @@@ static struct net_device *xennet_create
        netif_napi_add(netdev, &np->napi, xennet_poll, 64);
        netdev->features        = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
                                  NETIF_F_GSO_ROBUST;
-       netdev->hw_features     = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
+       netdev->hw_features     = NETIF_F_SG |
+                                 NETIF_F_IPV6_CSUM |
+                                 NETIF_F_TSO | NETIF_F_TSO6;
  
        /*
           * Assume that all hw features are available for now. This set
@@@ -1758,6 -1741,19 +1741,19 @@@ again
                goto abort_transaction;
        }
  
+       err = xenbus_write(xbt, dev->nodename, "feature-gso-tcpv6", "1");
+       if (err) {
+               message = "writing feature-gso-tcpv6";
+               goto abort_transaction;
+       }
+       err = xenbus_write(xbt, dev->nodename, "feature-ipv6-csum-offload",
+                          "1");
+       if (err) {
+               message = "writing feature-ipv6-csum-offload";
+               goto abort_transaction;
+       }
        err = xenbus_transaction_end(xbt, 0);
        if (err) {
                if (err == -EAGAIN)
@@@ -2115,7 -2111,7 +2111,7 @@@ static int __init netif_init(void
        if (!xen_domain())
                return -ENODEV;
  
 -      if (xen_hvm_domain() && !xen_platform_pci_unplug)
 +      if (!xen_has_pv_nic_devices())
                return -ENODEV;
  
        pr_info("Initialising Xen virtual ethernet driver\n");
diff --combined drivers/phy/Kconfig
index b901c472d7f3e2227d9003bf0ca8aac9f83c2af1,a8b17ce1642561680a54991fbf7951b5865171bb..afa2354f6600e72d904ea907ee92f775010ae8a9
@@@ -16,17 -16,12 +16,18 @@@ config GENERIC_PH
          framework should select this config.
  
  config PHY_EXYNOS_MIPI_VIDEO
+       depends on HAS_IOMEM
        tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
        help
          Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
          and EXYNOS SoCs.
  
 +config PHY_MVEBU_SATA
 +      def_bool y
 +      depends on ARCH_KIRKWOOD || ARCH_DOVE
 +      depends on OF
 +      select GENERIC_PHY
 +
  config OMAP_USB2
        tristate "OMAP USB2 PHY Driver"
        depends on ARCH_OMAP2PLUS
@@@ -57,10 -52,4 +58,10 @@@ config PHY_EXYNOS_DP_VIDE
        help
          Support for Display Port PHY found on Samsung EXYNOS SoCs.
  
 +config BCM_KONA_USB2_PHY
 +      tristate "Broadcom Kona USB2 PHY Driver"
 +      depends on GENERIC_PHY
 +      help
 +        Enable this to support the Broadcom Kona USB 2.0 PHY.
 +
  endmenu
diff --combined drivers/power/Kconfig
index 0196acf05231d1dff40e8f7917599ff176e01d48,32c6294c1668dee7c1cf13c8e61e839480d4accb..ba6975123071984b88195d3acbce7a6d5e79d8f7
@@@ -317,13 -317,6 +317,13 @@@ config CHARGER_MANAGE
            runtime and in suspend-to-RAM by waking up the system periodically
            with help of suspend_again support.
  
 +config CHARGER_MAX14577
 +      tristate "Maxim MAX14577 MUIC battery charger driver"
 +      depends on MFD_MAX14577
 +      help
 +        Say Y to enable support for the battery charger control sysfs and
 +        platform data of MAX14577 MUICs.
 +
  config CHARGER_MAX8997
        tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
        depends on MFD_MAX8997 && REGULATOR_MAX8997
@@@ -384,6 -377,7 +384,7 @@@ config AB8500_B
  config BATTERY_GOLDFISH
        tristate "Goldfish battery driver"
        depends on GOLDFISH || COMPILE_TEST
+       depends on HAS_IOMEM
        help
          Say Y to enable support for the battery and AC power in the
          Goldfish emulator.
index 64d94f77f8a742e9127d2ca1f029f6477068f2c4,19a2521ee17929893824ce74fe5d08b188225022..cb060364dfe7abd8933fd51e8c1c0003653052cf
@@@ -4,10 -4,12 +4,11 @@@
   * -----------------------------------------------------------------------------
   */
  
 -#include <linux/init.h>
  #include <linux/module.h>
  #include <linux/timer.h>
  #include <linux/sched.h>
  #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
  #include <linux/errno.h>
  #include <linux/ieee80211.h>
  #include "ozdbg.h"
@@@ -179,7 -181,7 +180,7 @@@ static struct oz_pd *oz_connect_req(str
                spin_lock_bh(&g_polling_lock);
                list_for_each(e, &g_pd_list) {
                        pd2 = container_of(e, struct oz_pd, link);
-                       if (memcmp(pd2->mac_addr, pd_addr, ETH_ALEN) == 0) {
+                       if (ether_addr_equal(pd2->mac_addr, pd_addr)) {
                                free_pd = pd;
                                pd = pd2;
                                break;
@@@ -336,7 -338,7 +337,7 @@@ static void oz_rx_frame(struct sk_buff 
        oz_dbg(RX_FRAMES, "RX frame PN=0x%x LPN=0x%x control=0x%x\n",
               oz_hdr->pkt_num, oz_hdr->last_pkt_num, oz_hdr->control);
        mac_hdr = skb_mac_header(skb);
 -      src_addr = &mac_hdr[ETH_ALEN] ;
 +      src_addr = &mac_hdr[ETH_ALEN];
        length = skb->len;
  
        /* Check the version field */
@@@ -596,7 -598,7 +597,7 @@@ struct oz_pd *oz_pd_find(const u8 *mac_
        spin_lock_bh(&g_polling_lock);
        list_for_each(e, &g_pd_list) {
                pd = container_of(e, struct oz_pd, link);
-               if (memcmp(pd->mac_addr, mac_addr, ETH_ALEN) == 0) {
+               if (ether_addr_equal(pd->mac_addr, mac_addr)) {
                        atomic_inc(&pd->ref_count);
                        spin_unlock_bh(&g_polling_lock);
                        return pd;
diff --combined fs/dlm/lowcomms.c
index a5e34dd6a32c91ac8bd7f85834e4f241a929bec8,ce53dffd23669734cedc0cf933f21b65c1fa18ab..3190ca973dd6be657a50b3cd8ff0f34b06a40fb1
@@@ -649,7 -649,6 +649,7 @@@ static void process_sctp_notification(s
                                      struct msghdr *msg, char *buf)
  {
        union sctp_notification *sn = (union sctp_notification *)buf;
 +      struct linger linger;
  
        switch (sn->sn_header.sn_type) {
        case SCTP_SEND_FAILED:
                                return;
  
                        /* Peel off a new sock */
-                       sctp_lock_sock(con->sock->sk);
+                       lock_sock(con->sock->sk);
                        ret = sctp_do_peeloff(con->sock->sk,
                                sn->sn_assoc_change.sac_assoc_id,
                                &new_con->sock);
-                       sctp_release_sock(con->sock->sk);
+                       release_sock(con->sock->sk);
                        if (ret < 0) {
                                log_print("Can't peel off a socket for "
                                          "connection %d to node %d: err=%d",
                        }
                        add_sock(new_con->sock, new_con);
  
 +                      linger.l_onoff = 1;
 +                      linger.l_linger = 0;
 +                      ret = kernel_setsockopt(new_con->sock, SOL_SOCKET, SO_LINGER,
 +                                              (char *)&linger, sizeof(linger));
 +                      if (ret < 0)
 +                              log_print("set socket option SO_LINGER failed");
 +
                        log_print("connecting to %d sctp association %d",
                                 nodeid, (int)sn->sn_assoc_change.sac_assoc_id);
  
diff --combined include/linux/kernel.h
index f74bb581ab649cbbec6f1c2abfcb5b4394f0aa85,03d8a6b0e2e803dc3c586041aa6e2dc126c7e80f..196d1ea86df081a5224928b4d75117aec85cd822
  #define ULLONG_MAX    (~0ULL)
  #define SIZE_MAX      (~(size_t)0)
  
 +#define U8_MAX                ((u8)~0U)
 +#define S8_MAX                ((s8)(U8_MAX>>1))
 +#define S8_MIN                ((s8)(-S8_MAX - 1))
 +#define U16_MAX               ((u16)~0U)
 +#define S16_MAX               ((s16)(U16_MAX>>1))
 +#define S16_MIN               ((s16)(-S16_MAX - 1))
 +#define U32_MAX               ((u32)~0U)
 +#define S32_MAX               ((s32)(U32_MAX>>1))
 +#define S32_MIN               ((s32)(-S32_MAX - 1))
 +#define U64_MAX               ((u64)~0ULL)
 +#define S64_MAX               ((s64)(U64_MAX>>1))
 +#define S64_MIN               ((s64)(-S64_MAX - 1))
 +
  #define STACK_MAGIC   0xdeadbeef
  
  #define REPEAT_BYTE(x)        ((~0ul / 0xff) * (x))
@@@ -206,6 -193,25 +206,25 @@@ extern int _cond_resched(void)
                (__x < 0) ? -__x : __x;         \
        })
  
+ /**
+  * reciprocal_scale - "scale" a value into range [0, ep_ro)
+  * @val: value
+  * @ep_ro: right open interval endpoint
+  *
+  * Perform a "reciprocal multiplication" in order to "scale" a value into
+  * range [0, ep_ro), where the upper interval endpoint is right-open.
+  * This is useful, e.g. for accessing a index of an array containing
+  * ep_ro elements, for example. Think of it as sort of modulus, only that
+  * the result isn't that of modulo. ;) Note that if initial input is a
+  * small value, then result will return 0.
+  *
+  * Return: a result based on val in interval [0, ep_ro).
+  */
+ static inline u32 reciprocal_scale(u32 val, u32 ep_ro)
+ {
+       return (u32)(((u64) val * ep_ro) >> 32);
+ }
  #if defined(CONFIG_MMU) && \
        (defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP))
  void might_fault(void);
@@@ -407,15 -413,6 +426,15 @@@ extern int panic_on_oops
  extern int panic_on_unrecovered_nmi;
  extern int panic_on_io_nmi;
  extern int sysctl_panic_on_stackoverflow;
 +/*
 + * Only to be used by arch init code. If the user over-wrote the default
 + * CONFIG_PANIC_TIMEOUT, honor it.
 + */
 +static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
 +{
 +      if (panic_timeout == arch_default_timeout)
 +              panic_timeout = timeout;
 +}
  extern const char *print_tainted(void);
  enum lockdep_ok {
        LOCKDEP_STILL_OK,
diff --combined include/linux/mlx4/cmd.h
index ff36620f88a70ef5c84f1a7f6e58fb519c0fb767,b0ec0fe035c0da27b3e8ffce43741781ae01c469..79a34723816895e59c794872f94d03893920c15b
@@@ -157,7 -157,6 +157,7 @@@ enum 
        /* register/delete flow steering network rules */
        MLX4_QP_FLOW_STEERING_ATTACH = 0x65,
        MLX4_QP_FLOW_STEERING_DETACH = 0x66,
 +      MLX4_FLOW_STEERING_IB_UC_QP_RANGE = 0x64,
  };
  
  enum {
@@@ -181,6 -180,7 +181,7 @@@ enum 
        MLX4_SET_PORT_GID_TABLE = 0x5,
        MLX4_SET_PORT_PRIO2TC   = 0x8,
        MLX4_SET_PORT_SCHEDULER = 0x9,
+       MLX4_SET_PORT_VXLAN     = 0xB
  };
  
  enum {
diff --combined include/linux/mlx4/cq.h
index e1862997f933ce7cc1c5d46d817e6f587d25222d,5dd0d70a06895b49e1d83db28968d0ebfdb179e0..e7ecc12a11636f1afe2f591e019da293ed1f517a
@@@ -34,7 -34,6 +34,7 @@@
  #define MLX4_CQ_H
  
  #include <linux/types.h>
 +#include <uapi/linux/if_ether.h>
  
  #include <linux/mlx4/device.h>
  #include <linux/mlx4/doorbell.h>
@@@ -44,15 -43,10 +44,15 @@@ struct mlx4_cqe 
        __be32                  immed_rss_invalid;
        __be32                  g_mlpath_rqpn;
        __be16                  sl_vid;
 -      __be16                  rlid;
 -      __be16                  status;
 -      u8                      ipv6_ext_mask;
 -      u8                      badfcs_enc;
 +      union {
 +              struct {
 +                      __be16  rlid;
 +                      __be16  status;
 +                      u8      ipv6_ext_mask;
 +                      u8      badfcs_enc;
 +              };
 +              u8  smac[ETH_ALEN];
 +      };
        __be32                  byte_cnt;
        __be16                  wqe_index;
        __be16                  checksum;
@@@ -87,9 -81,13 +87,14 @@@ struct mlx4_ts_cqe 
  } __packed;
  
  enum {
+       MLX4_CQE_L2_TUNNEL_IPOK         = 1 << 31,
        MLX4_CQE_VLAN_PRESENT_MASK      = 1 << 29,
+       MLX4_CQE_L2_TUNNEL              = 1 << 27,
+       MLX4_CQE_L2_TUNNEL_CSUM         = 1 << 26,
+       MLX4_CQE_L2_TUNNEL_IPV4         = 1 << 25,
        MLX4_CQE_QPN_MASK               = 0xffffff,
 +      MLX4_CQE_VID_MASK               = 0xfff,
  };
  
  enum {
index ac5cb1d92487c4dc5b1512999a719bd34ab927f7,c99ecf6d2c675f53dc127058638ea5f9d501cb8d..5edd2c68274dd449f34f557296ce789e38578dad
@@@ -118,6 -118,11 +118,11 @@@ static inline const char *mlx4_steering
        }
  }
  
+ enum {
+       MLX4_TUNNEL_OFFLOAD_MODE_NONE,
+       MLX4_TUNNEL_OFFLOAD_MODE_VXLAN
+ };
  enum {
        MLX4_DEV_CAP_FLAG_RC            = 1LL <<  0,
        MLX4_DEV_CAP_FLAG_UC            = 1LL <<  1,
@@@ -161,7 -166,7 +166,8 @@@ enum 
        MLX4_DEV_CAP_FLAG2_VLAN_CONTROL         = 1LL <<  6,
        MLX4_DEV_CAP_FLAG2_FSM                  = 1LL <<  7,
        MLX4_DEV_CAP_FLAG2_UPDATE_QP            = 1LL <<  8,
-       MLX4_DEV_CAP_FLAG2_DMFS_IPOIB           = 1LL <<  9
 -      MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS       = 1LL <<  9
++      MLX4_DEV_CAP_FLAG2_DMFS_IPOIB           = 1LL <<  9,
++      MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS       = 1LL <<  10,
  };
  
  enum {
@@@ -455,6 -460,8 +461,8 @@@ struct mlx4_caps 
        u32                     userspace_caps; /* userspace must be aware of these */
        u32                     function_caps;  /* VFs must be aware of these */
        u16                     hca_core_clock;
+       u64                     phys_port_id[MLX4_MAX_PORTS + 1];
+       int                     tunnel_offload_mode;
  };
  
  struct mlx4_buf_list {
@@@ -909,6 -916,7 +917,7 @@@ enum mlx4_net_trans_rule_id 
        MLX4_NET_TRANS_RULE_ID_IPV4,
        MLX4_NET_TRANS_RULE_ID_TCP,
        MLX4_NET_TRANS_RULE_ID_UDP,
+       MLX4_NET_TRANS_RULE_ID_VXLAN,
        MLX4_NET_TRANS_RULE_NUM, /* should be last */
  };
  
@@@ -966,6 -974,12 +975,12 @@@ struct mlx4_spec_ib 
        u8      dst_gid_msk[16];
  };
  
+ struct mlx4_spec_vxlan {
+       __be32 vni;
+       __be32 vni_mask;
+ };
  struct mlx4_spec_list {
        struct  list_head list;
        enum    mlx4_net_trans_rule_id id;
                struct mlx4_spec_ib ib;
                struct mlx4_spec_ipv4 ipv4;
                struct mlx4_spec_tcp_udp tcp_udp;
+               struct mlx4_spec_vxlan vxlan;
        };
  };
  
@@@ -1060,6 -1075,15 +1076,15 @@@ struct mlx4_net_trans_rule_hw_ipv4 
        __be32  src_ip_msk;
  } __packed;
  
+ struct mlx4_net_trans_rule_hw_vxlan {
+       u8      size;
+       u8      rsvd;
+       __be16  id;
+       __be32  rsvd1;
+       __be32  vni;
+       __be32  vni_mask;
+ } __packed;
  struct _rule_hw {
        union {
                struct {
                struct mlx4_net_trans_rule_hw_ib ib;
                struct mlx4_net_trans_rule_hw_ipv4 ipv4;
                struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp;
+               struct mlx4_net_trans_rule_hw_vxlan vxlan;
        };
  };
  
+ enum {
+       VXLAN_STEER_BY_OUTER_MAC        = 1 << 0,
+       VXLAN_STEER_BY_OUTER_VLAN       = 1 << 1,
+       VXLAN_STEER_BY_VSID_VNI         = 1 << 2,
+       VXLAN_STEER_BY_INNER_MAC        = 1 << 3,
+       VXLAN_STEER_BY_INNER_VLAN       = 1 << 4,
+ };
  int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn,
                                enum mlx4_net_trans_promisc_mode mode);
  int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
@@@ -1096,7 -1130,7 +1131,8 @@@ int mlx4_SET_PORT_qpn_calc(struct mlx4_
  int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
  int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
                u8 *pg, u16 *ratelimit);
+ int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering);
 +int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx);
  int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
  int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
  void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);
@@@ -1115,6 -1149,7 +1151,7 @@@ int mlx4_assign_eq(struct mlx4_dev *dev
                   int *vector);
  void mlx4_release_eq(struct mlx4_dev *dev, int vec);
  
+ int mlx4_get_phys_port_id(struct mlx4_dev *dev);
  int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port);
  int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port);
  
@@@ -1146,9 -1181,6 +1183,9 @@@ int set_and_calc_slave_port_state(struc
  void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid);
  __be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave);
  
 +int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
 +                                    u32 max_range_qpn);
 +
  cycle_t mlx4_read_clock(struct mlx4_dev *dev);
  
  #endif /* MLX4_DEVICE_H */
diff --combined include/linux/printk.h
index cc6f74d65167b47f4a59da3c8af04190329cf6f5,26fb95ce5080dec51eb9c1f654ac81af87e53a07..fa47e2708c01748a958f40300c900673cfaa3777
@@@ -5,7 -5,6 +5,7 @@@
  #include <linux/init.h>
  #include <linux/kern_levels.h>
  #include <linux/linkage.h>
 +#include <linux/cache.h>
  
  extern const char linux_banner[];
  extern const char linux_proc_banner[];
@@@ -88,6 -87,13 +88,13 @@@ struct va_format 
   */
  #define HW_ERR                "[Hardware Error]: "
  
+ /*
+  * DEPRECATED
+  * Add this to a message whenever you want to warn user space about the use
+  * of a deprecated aspect of an API so they can stop using it
+  */
+ #define DEPRECATED    "[Deprecated]: "
  /*
   * Dummy printk for disabled debugging statements to use whilst maintaining
   * gcc's format and side-effect checking.
@@@ -254,17 -260,17 +261,17 @@@ extern asmlinkage void dump_stack(void
   */
  
  #ifdef CONFIG_PRINTK
 -#define printk_once(fmt, ...)                 \
 -({                                            \
 -      static bool __print_once;               \
 -                                              \
 -      if (!__print_once) {                    \
 -              __print_once = true;            \
 -              printk(fmt, ##__VA_ARGS__);     \
 -      }                                       \
 +#define printk_once(fmt, ...)                                 \
 +({                                                            \
 +      static bool __print_once __read_mostly;                 \
 +                                                              \
 +      if (!__print_once) {                                    \
 +              __print_once = true;                            \
 +              printk(fmt, ##__VA_ARGS__);                     \
 +      }                                                       \
  })
  #else
 -#define printk_once(fmt, ...)                 \
 +#define printk_once(fmt, ...)                                 \
        no_printk(fmt, ##__VA_ARGS__)
  #endif
  
diff --combined include/linux/slab_def.h
index 40fc39d22d53a3e8ca25122154861877cf946f94,96e8abae19a943375e39da1c779016a72cc07b7e..8235dfbb3b050e090868b35c2abc143ef5cf253b
@@@ -1,18 -1,20 +1,20 @@@
  #ifndef _LINUX_SLAB_DEF_H
  #define       _LINUX_SLAB_DEF_H
  
+ #include <linux/reciprocal_div.h>
  /*
   * Definitions unique to the original Linux SLAB allocator.
   */
  
  struct kmem_cache {
 -/* 1) Cache tunables. Protected by cache_chain_mutex */
 +/* 1) Cache tunables. Protected by slab_mutex */
        unsigned int batchcount;
        unsigned int limit;
        unsigned int shared;
  
        unsigned int size;
-       u32 reciprocal_buffer_size;
+       struct reciprocal_value reciprocal_buffer_size;
  /* 2) touched by every alloc & free from the backend */
  
        unsigned int flags;             /* constant flags */
diff --combined include/net/netlabel.h
index 97e6dcaf12bb4860124336c7a3081d82389ac773,24948bedb64cf8cc055976e31646a204ec090683..4fe018c48ed9fc796545e172cba8e2cea62f21ff
@@@ -22,8 -22,7 +22,7 @@@
   * the GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
-  * along with this program;  if not, write to the Free Software
-  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  * along with this program;  if not, see <http://www.gnu.org/licenses/>.
   *
   */
  
@@@ -111,7 -110,7 +110,7 @@@ struct cipso_v4_doi
  struct netlbl_audit {
        u32 secid;
        kuid_t loginuid;
 -      u32 sessionid;
 +      unsigned int sessionid;
  };
  
  /*
diff --combined include/net/xfrm.h
index 1d535f4d3873a67a811174f0d4df34494da250e8,cd7c46ff6f1f41e7a6449c912fb7e0419e281e8f..afa5730fb3bd2ff810f63f861f1b52b29e34c965
@@@ -53,7 -53,6 +53,6 @@@
  #define XFRM_INC_STATS_USER(net, field)       ((void)(net))
  #endif
  
- extern struct mutex xfrm_cfg_mutex;
  
  /* Organization of SPD aka "XFRM rules"
     ------------------------------------
@@@ -681,7 -680,7 +680,7 @@@ struct xfrm_spi_skb_cb 
  struct xfrm_audit {
        u32     secid;
        kuid_t  loginuid;
 -      u32     sessionid;
 +      unsigned int sessionid;
  };
  
  #ifdef CONFIG_AUDITSYSCALL
@@@ -699,7 -698,7 +698,7 @@@ static inline struct audit_buffer *xfrm
        return audit_buf;
  }
  
 -static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid,
 +static inline void xfrm_audit_helper_usrinfo(kuid_t auid, unsigned int ses, u32 secid,
                                             struct audit_buffer *audit_buf)
  {
        char *secctx;
  }
  
  void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, kuid_t auid,
 -                         u32 ses, u32 secid);
 +                         unsigned int ses, u32 secid);
  void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, kuid_t auid,
 -                            u32 ses, u32 secid);
 +                            unsigned int ses, u32 secid);
  void xfrm_audit_state_add(struct xfrm_state *x, int result, kuid_t auid,
 -                        u32 ses, u32 secid);
 +                        unsigned int ses, u32 secid);
  void xfrm_audit_state_delete(struct xfrm_state *x, int result, kuid_t auid,
 -                           u32 ses, u32 secid);
 +                           unsigned int ses, u32 secid);
  void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
                                      struct sk_buff *skb);
  void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
@@@ -735,22 -734,22 +734,22 @@@ void xfrm_audit_state_icvfail(struct xf
  #else
  
  static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
 -                                kuid_t auid, u32 ses, u32 secid)
 +                                kuid_t auid, unsigned int ses, u32 secid)
  {
  }
  
  static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
 -                                kuid_t auid, u32 ses, u32 secid)
 +                                kuid_t auid, unsigned int ses, u32 secid)
  {
  }
  
  static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
 -                               kuid_t auid, u32 ses, u32 secid)
 +                               kuid_t auid, unsigned int ses, u32 secid)
  {
  }
  
  static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
 -                                  kuid_t auid, u32 ses, u32 secid)
 +                                  kuid_t auid, unsigned int ses, u32 secid)
  {
  }
  
@@@ -1409,7 -1408,7 +1408,7 @@@ static inline void xfrm_sysctl_fini(str
  void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
  int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
                    int (*func)(struct xfrm_state *, int, void*), void *);
- void xfrm_state_walk_done(struct xfrm_state_walk *walk);
+ void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
  struct xfrm_state *xfrm_state_alloc(struct net *net);
  struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
                                   const xfrm_address_t *saddr,
@@@ -1422,6 -1421,8 +1421,8 @@@ struct xfrm_state *xfrm_stateonly_find(
                                       xfrm_address_t *saddr,
                                       unsigned short family,
                                       u8 mode, u8 proto, u32 reqid);
+ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
+                                             unsigned short family);
  int xfrm_state_check_expire(struct xfrm_state *x);
  void xfrm_state_insert(struct xfrm_state *x);
  int xfrm_state_add(struct xfrm_state *x);
@@@ -1436,12 -1437,12 +1437,12 @@@ struct xfrm_state *xfrm_state_lookup_by
                                            unsigned short family);
  #ifdef CONFIG_XFRM_SUB_POLICY
  int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
-                  unsigned short family);
+                  unsigned short family, struct net *net);
  int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
                    unsigned short family);
  #else
  static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
-                                int n, unsigned short family)
+                                int n, unsigned short family, struct net *net)
  {
        return -ENOSYS;
  }
@@@ -1553,7 -1554,7 +1554,7 @@@ void xfrm_policy_walk_init(struct xfrm_
  int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
                     int (*func)(struct xfrm_policy *, int, int, void*),
                     void *);
- void xfrm_policy_walk_done(struct xfrm_policy_walk *walk);
+ void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
  int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
  struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark,
                                          u8 type, int dir,
@@@ -1564,6 -1565,7 +1565,7 @@@ struct xfrm_policy *xfrm_policy_byid(st
                                     u32 id, int delete, int *err);
  int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
  u32 xfrm_get_acqseq(void);
+ int verify_spi_info(u8 proto, u32 min, u32 max);
  int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
  struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
                                 u8 mode, u32 reqid, u8 proto,
@@@ -1576,12 -1578,12 +1578,12 @@@ int xfrm_sk_policy_insert(struct sock *
  int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
               const struct xfrm_migrate *m, int num_bundles,
               const struct xfrm_kmaddress *k);
- struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m);
+ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
  struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
                                      struct xfrm_migrate *m);
  int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
                 struct xfrm_migrate *m, int num_bundles,
-                struct xfrm_kmaddress *k);
+                struct xfrm_kmaddress *k, struct net *net);
  #endif
  
  int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
index ab6b4e7f66574a1edd7ca3f46ca8488bea43ae0f,c870c2a71d65e9355c068b4148a8e4851cc11baf..30db069bce62c6533b72a65e4c89f536a448c79d
  #define  PCI_EXP_LNKSTA_CLS   0x000f  /* Current Link Speed */
  #define  PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 /* Current Link Speed 2.5GT/s */
  #define  PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */
+ #define  PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */
  #define  PCI_EXP_LNKSTA_NLW   0x03f0  /* Negotiated Link Width */
+ #define  PCI_EXP_LNKSTA_NLW_X1        0x0010  /* Current Link Width x1 */
+ #define  PCI_EXP_LNKSTA_NLW_X2        0x0020  /* Current Link Width x2 */
+ #define  PCI_EXP_LNKSTA_NLW_X4        0x0040  /* Current Link Width x4 */
+ #define  PCI_EXP_LNKSTA_NLW_X8        0x0080  /* Current Link Width x8 */
  #define  PCI_EXP_LNKSTA_NLW_SHIFT 4   /* start of NLW mask in link status */
  #define  PCI_EXP_LNKSTA_LT    0x0800  /* Link Training */
  #define  PCI_EXP_LNKSTA_SLC   0x1000  /* Slot Clock Configuration */
  #define  PCI_EXP_SLTCTL_CCIE  0x0010  /* Command Completed Interrupt Enable */
  #define  PCI_EXP_SLTCTL_HPIE  0x0020  /* Hot-Plug Interrupt Enable */
  #define  PCI_EXP_SLTCTL_AIC   0x00c0  /* Attention Indicator Control */
 +#define  PCI_EXP_SLTCTL_ATTN_IND_ON    0x0040 /* Attention Indicator on */
 +#define  PCI_EXP_SLTCTL_ATTN_IND_BLINK 0x0080 /* Attention Indicator blinking */
 +#define  PCI_EXP_SLTCTL_ATTN_IND_OFF   0x00c0 /* Attention Indicator off */
  #define  PCI_EXP_SLTCTL_PIC   0x0300  /* Power Indicator Control */
 +#define  PCI_EXP_SLTCTL_PWR_IND_ON     0x0100 /* Power Indicator on */
 +#define  PCI_EXP_SLTCTL_PWR_IND_BLINK  0x0200 /* Power Indicator blinking */
 +#define  PCI_EXP_SLTCTL_PWR_IND_OFF    0x0300 /* Power Indicator off */
  #define  PCI_EXP_SLTCTL_PCC   0x0400  /* Power Controller Control */
 +#define  PCI_EXP_SLTCTL_PWR_ON         0x0000 /* Power On */
 +#define  PCI_EXP_SLTCTL_PWR_OFF        0x0400 /* Power Off */
  #define  PCI_EXP_SLTCTL_EIC   0x0800  /* Electromechanical Interlock Control */
  #define  PCI_EXP_SLTCTL_DLLSCE        0x1000  /* Data Link Layer State Changed Enable */
  #define PCI_EXP_SLTSTA                26      /* Slot Status */
  #define PCI_ERR_ROOT_ERR_SRC  52      /* Error Source Identification */
  
  /* Virtual Channel */
 -#define PCI_VC_PORT_REG1      4
 -#define  PCI_VC_REG1_EVCC     0x7     /* extended VC count */
 -#define PCI_VC_PORT_REG2      8
 -#define  PCI_VC_REG2_32_PHASE 0x2
 -#define  PCI_VC_REG2_64_PHASE 0x4
 -#define  PCI_VC_REG2_128_PHASE        0x8
 +#define PCI_VC_PORT_CAP1      4
 +#define  PCI_VC_CAP1_EVCC     0x00000007      /* extended VC count */
 +#define  PCI_VC_CAP1_LPEVCC   0x00000070      /* low prio extended VC count */
 +#define  PCI_VC_CAP1_ARB_SIZE 0x00000c00
 +#define PCI_VC_PORT_CAP2      8
 +#define  PCI_VC_CAP2_32_PHASE         0x00000002
 +#define  PCI_VC_CAP2_64_PHASE         0x00000004
 +#define  PCI_VC_CAP2_128_PHASE                0x00000008
 +#define  PCI_VC_CAP2_ARB_OFF          0xff000000
  #define PCI_VC_PORT_CTRL      12
 +#define  PCI_VC_PORT_CTRL_LOAD_TABLE  0x00000001
  #define PCI_VC_PORT_STATUS    14
 +#define  PCI_VC_PORT_STATUS_TABLE     0x00000001
  #define PCI_VC_RES_CAP                16
 +#define  PCI_VC_RES_CAP_32_PHASE      0x00000002
 +#define  PCI_VC_RES_CAP_64_PHASE      0x00000004
 +#define  PCI_VC_RES_CAP_128_PHASE     0x00000008
 +#define  PCI_VC_RES_CAP_128_PHASE_TB  0x00000010
 +#define  PCI_VC_RES_CAP_256_PHASE     0x00000020
 +#define  PCI_VC_RES_CAP_ARB_OFF               0xff000000
  #define PCI_VC_RES_CTRL               20
 +#define  PCI_VC_RES_CTRL_LOAD_TABLE   0x00010000
 +#define  PCI_VC_RES_CTRL_ARB_SELECT   0x000e0000
 +#define  PCI_VC_RES_CTRL_ID           0x07000000
 +#define  PCI_VC_RES_CTRL_ENABLE               0x80000000
  #define PCI_VC_RES_STATUS     26
 +#define  PCI_VC_RES_STATUS_TABLE      0x00000001
 +#define  PCI_VC_RES_STATUS_NEGO               0x00000002
  #define PCI_CAP_VC_BASE_SIZEOF                0x10
  #define PCI_CAP_VC_PER_VC_SIZEOF      0x0C
  
diff --combined lib/Makefile
index 98ec3b861062d5ac8afe4cdcb72491b42bc9a75c,d0f79c547d97953549f2420d9b9b52edd6a77ed5..126b34f2eb1663dcc9636ca71647e05736708689
@@@ -26,13 -26,11 +26,13 @@@ obj-y += bcd.o div64.o sort.o parser.o 
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
         gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
         bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
-        percpu-refcount.o percpu_ida.o
+        percpu-refcount.o percpu_ida.o hash.o
  obj-y += string_helpers.o
  obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
  obj-y += kstrtox.o
  obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
 +obj-$(CONFIG_TEST_MODULE) += test_module.o
 +obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
  
  ifeq ($(CONFIG_DEBUG_KOBJECT),y)
  CFLAGS_kobject.o += -DDEBUG
diff --combined net/core/dev.c
index 2e0c6a90f6f2fdd02ac4b2c5ceb03544a4cd16ab,d89931bae25b46eff6ebb218b989e4c655e779d7..3721db71635051f82a4ace0d24e669156c1a8783
@@@ -147,6 -147,8 +147,8 @@@ struct list_head ptype_base[PTYPE_HASH_
  struct list_head ptype_all __read_mostly;     /* Taps */
  static struct list_head offload_base __read_mostly;
  
+ static int netif_rx_internal(struct sk_buff *skb);
  /*
   * The @dev_base_head list is protected by @dev_base_lock and the rtnl
   * semaphore.
@@@ -480,7 -482,7 +482,7 @@@ EXPORT_SYMBOL(dev_add_offload)
   *    and must not be freed until after all the CPU's have gone
   *    through a quiescent state.
   */
- void __dev_remove_offload(struct packet_offload *po)
static void __dev_remove_offload(struct packet_offload *po)
  {
        struct list_head *head = &offload_base;
        struct packet_offload *po1;
  out:
        spin_unlock(&offload_lock);
  }
- EXPORT_SYMBOL(__dev_remove_offload);
  
  /**
   *    dev_remove_offload       - remove packet offload handler
@@@ -1118,6 -1119,8 +1119,8 @@@ rollback
  
        write_seqcount_end(&devnet_rename_seq);
  
+       netdev_adjacent_rename_links(dev, oldname);
        write_lock_bh(&dev_base_lock);
        hlist_del_rcu(&dev->name_hlist);
        write_unlock_bh(&dev_base_lock);
                        err = ret;
                        write_seqcount_begin(&devnet_rename_seq);
                        memcpy(dev->name, oldname, IFNAMSIZ);
+                       memcpy(oldname, newname, IFNAMSIZ);
                        goto rollback;
                } else {
                        pr_err("%s: name change rollback failed: %d\n",
@@@ -1566,14 -1570,14 +1570,14 @@@ EXPORT_SYMBOL(unregister_netdevice_noti
   *    are as for raw_notifier_call_chain().
   */
  
- int call_netdevice_notifiers_info(unsigned long val, struct net_device *dev,
-                                 struct netdev_notifier_info *info)
+ static int call_netdevice_notifiers_info(unsigned long val,
+                                        struct net_device *dev,
+                                        struct netdev_notifier_info *info)
  {
        ASSERT_RTNL();
        netdev_notifier_info_init(info, dev);
        return raw_notifier_call_chain(&netdev_chain, val, info);
  }
- EXPORT_SYMBOL(call_netdevice_notifiers_info);
  
  /**
   *    call_netdevice_notifiers - call all network notifier blocks
@@@ -1699,7 -1703,7 +1703,7 @@@ int dev_forward_skb(struct net_device *
        skb_scrub_packet(skb, true);
        skb->protocol = eth_type_trans(skb, dev);
  
-       return netif_rx(skb);
+       return netif_rx_internal(skb);
  }
  EXPORT_SYMBOL_GPL(dev_forward_skb);
  
@@@ -2079,7 -2083,7 +2083,7 @@@ int netif_set_real_num_tx_queues(struc
  }
  EXPORT_SYMBOL(netif_set_real_num_tx_queues);
  
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
  /**
   *    netif_set_real_num_rx_queues - set actual number of RX queues used
   *    @dev: Network device
@@@ -2145,30 -2149,42 +2149,42 @@@ void __netif_schedule(struct Qdisc *q
  }
  EXPORT_SYMBOL(__netif_schedule);
  
- void dev_kfree_skb_irq(struct sk_buff *skb)
+ struct dev_kfree_skb_cb {
+       enum skb_free_reason reason;
+ };
+ static struct dev_kfree_skb_cb *get_kfree_skb_cb(const struct sk_buff *skb)
  {
-       if (atomic_dec_and_test(&skb->users)) {
-               struct softnet_data *sd;
-               unsigned long flags;
+       return (struct dev_kfree_skb_cb *)skb->cb;
+ }
+ void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason)
+ {
+       unsigned long flags;
  
-               local_irq_save(flags);
-               sd = &__get_cpu_var(softnet_data);
-               skb->next = sd->completion_queue;
-               sd->completion_queue = skb;
-               raise_softirq_irqoff(NET_TX_SOFTIRQ);
-               local_irq_restore(flags);
+       if (likely(atomic_read(&skb->users) == 1)) {
+               smp_rmb();
+               atomic_set(&skb->users, 0);
+       } else if (likely(!atomic_dec_and_test(&skb->users))) {
+               return;
        }
+       get_kfree_skb_cb(skb)->reason = reason;
+       local_irq_save(flags);
+       skb->next = __this_cpu_read(softnet_data.completion_queue);
+       __this_cpu_write(softnet_data.completion_queue, skb);
+       raise_softirq_irqoff(NET_TX_SOFTIRQ);
+       local_irq_restore(flags);
  }
- EXPORT_SYMBOL(dev_kfree_skb_irq);
+ EXPORT_SYMBOL(__dev_kfree_skb_irq);
  
- void dev_kfree_skb_any(struct sk_buff *skb)
+ void __dev_kfree_skb_any(struct sk_buff *skb, enum skb_free_reason reason)
  {
        if (in_irq() || irqs_disabled())
-               dev_kfree_skb_irq(skb);
+               __dev_kfree_skb_irq(skb, reason);
        else
                dev_kfree_skb(skb);
  }
- EXPORT_SYMBOL(dev_kfree_skb_any);
+ EXPORT_SYMBOL(__dev_kfree_skb_any);
  
  
  /**
@@@ -2442,13 -2458,8 +2458,8 @@@ static void dev_gso_skb_destructor(stru
  {
        struct dev_gso_cb *cb;
  
-       do {
-               struct sk_buff *nskb = skb->next;
-               skb->next = nskb->next;
-               nskb->next = NULL;
-               kfree_skb(nskb);
-       } while (skb->next);
+       kfree_skb_list(skb->next);
+       skb->next = NULL;
  
        cb = DEV_GSO_CB(skb);
        if (cb->destructor)
@@@ -2523,21 -2534,6 +2534,6 @@@ netdev_features_t netif_skb_features(st
  }
  EXPORT_SYMBOL(netif_skb_features);
  
- /*
-  * Returns true if either:
-  *    1. skb has frag_list and the device doesn't support FRAGLIST, or
-  *    2. skb is fragmented and the device does not support SG.
-  */
- static inline int skb_needs_linearize(struct sk_buff *skb,
-                                     netdev_features_t features)
- {
-       return skb_is_nonlinear(skb) &&
-                       ((skb_has_frag_list(skb) &&
-                               !(features & NETIF_F_FRAGLIST)) ||
-                       (skb_shinfo(skb)->nr_frags &&
-                               !(features & NETIF_F_SG)));
- }
  int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        struct netdev_queue *txq)
  {
                        dev_queue_xmit_nit(skb, dev);
  
                skb_len = skb->len;
-                       rc = ops->ndo_start_xmit(skb, dev);
+               trace_net_dev_start_xmit(skb, dev);
+               rc = ops->ndo_start_xmit(skb, dev);
                trace_net_dev_xmit(skb, rc, dev, skb_len);
                if (rc == NETDEV_TX_OK)
                        txq_trans_update(txq);
@@@ -2624,6 -2620,7 +2620,7 @@@ gso
                        dev_queue_xmit_nit(nskb, dev);
  
                skb_len = nskb->len;
+               trace_net_dev_start_xmit(nskb, dev);
                rc = ops->ndo_start_xmit(nskb, dev);
                trace_net_dev_xmit(nskb, rc, dev, skb_len);
                if (unlikely(rc != NETDEV_TX_OK)) {
@@@ -2744,7 -2741,7 +2741,7 @@@ static inline int __dev_xmit_skb(struc
        return rc;
  }
  
- #if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
+ #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
  static void skb_update_prio(struct sk_buff *skb)
  {
        struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
@@@ -2781,8 -2778,9 +2778,9 @@@ int dev_loopback_xmit(struct sk_buff *s
  EXPORT_SYMBOL(dev_loopback_xmit);
  
  /**
-  *    dev_queue_xmit - transmit a buffer
+  *    __dev_queue_xmit - transmit a buffer
   *    @skb: buffer to transmit
+  *    @accel_priv: private data used for L2 forwarding offload
   *
   *    Queue a buffer for transmission to a network device. The caller must
   *    have set the device and priority and built the buffer before calling
@@@ -3014,7 -3012,7 +3012,7 @@@ static int get_rps_cpu(struct net_devic
        }
  
        skb_reset_network_header(skb);
-       if (!skb_get_rxhash(skb))
+       if (!skb_get_hash(skb))
                goto done;
  
        flow_table = rcu_dereference(rxqueue->rps_flow_table);
@@@ -3159,7 -3157,7 +3157,7 @@@ static bool skb_flow_limit(struct sk_bu
        rcu_read_lock();
        fl = rcu_dereference(sd->flow_limit);
        if (fl) {
-               new_flow = skb_get_rxhash(skb) & (fl->num_buckets - 1);
+               new_flow = skb_get_hash(skb) & (fl->num_buckets - 1);
                old_flow = fl->history[fl->history_head];
                fl->history[fl->history_head] = new_flow;
  
@@@ -3227,22 -3225,7 +3225,7 @@@ enqueue
        return NET_RX_DROP;
  }
  
- /**
-  *    netif_rx        -       post buffer to the network code
-  *    @skb: buffer to post
-  *
-  *    This function receives a packet from a device driver and queues it for
-  *    the upper (protocol) levels to process.  It always succeeds. The buffer
-  *    may be dropped during processing for congestion control or by the
-  *    protocol layers.
-  *
-  *    return values:
-  *    NET_RX_SUCCESS  (no congestion)
-  *    NET_RX_DROP     (packet was dropped)
-  *
-  */
- int netif_rx(struct sk_buff *skb)
+ static int netif_rx_internal(struct sk_buff *skb)
  {
        int ret;
  
        }
        return ret;
  }
+ /**
+  *    netif_rx        -       post buffer to the network code
+  *    @skb: buffer to post
+  *
+  *    This function receives a packet from a device driver and queues it for
+  *    the upper (protocol) levels to process.  It always succeeds. The buffer
+  *    may be dropped during processing for congestion control or by the
+  *    protocol layers.
+  *
+  *    return values:
+  *    NET_RX_SUCCESS  (no congestion)
+  *    NET_RX_DROP     (packet was dropped)
+  *
+  */
+ int netif_rx(struct sk_buff *skb)
+ {
+       trace_netif_rx_entry(skb);
+       return netif_rx_internal(skb);
+ }
  EXPORT_SYMBOL(netif_rx);
  
  int netif_rx_ni(struct sk_buff *skb)
  {
        int err;
  
+       trace_netif_rx_ni_entry(skb);
        preempt_disable();
-       err = netif_rx(skb);
+       err = netif_rx_internal(skb);
        if (local_softirq_pending())
                do_softirq();
        preempt_enable();
@@@ -3311,7 -3318,10 +3318,10 @@@ static void net_tx_action(struct softir
                        clist = clist->next;
  
                        WARN_ON(atomic_read(&skb->users));
-                       trace_kfree_skb(skb, net_tx_action);
+                       if (likely(get_kfree_skb_cb(skb)->reason == SKB_REASON_CONSUMED))
+                               trace_consume_skb(skb);
+                       else
+                               trace_kfree_skb(skb, net_tx_action);
                        __kfree_skb(skb);
                }
        }
@@@ -3667,22 -3677,7 +3677,7 @@@ static int __netif_receive_skb(struct s
        return ret;
  }
  
- /**
-  *    netif_receive_skb - process receive buffer from network
-  *    @skb: buffer to process
-  *
-  *    netif_receive_skb() is the main receive data processing function.
-  *    It always succeeds. The buffer may be dropped during processing
-  *    for congestion control or by the protocol layers.
-  *
-  *    This function may only be called from softirq context and interrupts
-  *    should be enabled.
-  *
-  *    Return values (usually ignored):
-  *    NET_RX_SUCCESS: no congestion
-  *    NET_RX_DROP: packet was dropped
-  */
- int netif_receive_skb(struct sk_buff *skb)
+ static int netif_receive_skb_internal(struct sk_buff *skb)
  {
        net_timestamp_check(netdev_tstamp_prequeue, skb);
  
  #endif
        return __netif_receive_skb(skb);
  }
+ /**
+  *    netif_receive_skb - process receive buffer from network
+  *    @skb: buffer to process
+  *
+  *    netif_receive_skb() is the main receive data processing function.
+  *    It always succeeds. The buffer may be dropped during processing
+  *    for congestion control or by the protocol layers.
+  *
+  *    This function may only be called from softirq context and interrupts
+  *    should be enabled.
+  *
+  *    Return values (usually ignored):
+  *    NET_RX_SUCCESS: no congestion
+  *    NET_RX_DROP: packet was dropped
+  */
+ int netif_receive_skb(struct sk_buff *skb)
+ {
+       trace_netif_receive_skb_entry(skb);
+       return netif_receive_skb_internal(skb);
+ }
  EXPORT_SYMBOL(netif_receive_skb);
  
  /* Network device is going away, flush any packets still pending
@@@ -3757,7 -3774,7 +3774,7 @@@ static int napi_gro_complete(struct sk_
                if (ptype->type != type || !ptype->callbacks.gro_complete)
                        continue;
  
-               err = ptype->callbacks.gro_complete(skb);
+               err = ptype->callbacks.gro_complete(skb, 0);
                break;
        }
        rcu_read_unlock();
        }
  
  out:
-       return netif_receive_skb(skb);
+       return netif_receive_skb_internal(skb);
  }
  
  /* napi->gro_list contains packets ordered by age.
@@@ -3805,10 -3822,18 +3822,18 @@@ static void gro_list_prepare(struct nap
  {
        struct sk_buff *p;
        unsigned int maclen = skb->dev->hard_header_len;
+       u32 hash = skb_get_hash_raw(skb);
  
        for (p = napi->gro_list; p; p = p->next) {
                unsigned long diffs;
  
+               NAPI_GRO_CB(p)->flush = 0;
+               if (hash != skb_get_hash_raw(p)) {
+                       NAPI_GRO_CB(p)->same_flow = 0;
+                       continue;
+               }
                diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
                diffs |= p->vlan_tci ^ skb->vlan_tci;
                if (maclen == ETH_HLEN)
                                       skb_gro_mac_header(skb),
                                       maclen);
                NAPI_GRO_CB(p)->same_flow = !diffs;
-               NAPI_GRO_CB(p)->flush = 0;
+       }
+ }
+ static void skb_gro_reset_offset(struct sk_buff *skb)
+ {
+       const struct skb_shared_info *pinfo = skb_shinfo(skb);
+       const skb_frag_t *frag0 = &pinfo->frags[0];
+       NAPI_GRO_CB(skb)->data_offset = 0;
+       NAPI_GRO_CB(skb)->frag0 = NULL;
+       NAPI_GRO_CB(skb)->frag0_len = 0;
+       if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
+           pinfo->nr_frags &&
+           !PageHighMem(skb_frag_page(frag0))) {
+               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+               NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
        }
  }
  
@@@ -3838,7 -3879,9 +3879,9 @@@ static enum gro_result dev_gro_receive(
        if (skb_is_gso(skb) || skb_has_frag_list(skb))
                goto normal;
  
+       skb_gro_reset_offset(skb);
        gro_list_prepare(napi, skb);
+       NAPI_GRO_CB(skb)->csum = skb->csum; /* Needed for CHECKSUM_COMPLETE */
  
        rcu_read_lock();
        list_for_each_entry_rcu(ptype, head, list) {
                NAPI_GRO_CB(skb)->same_flow = 0;
                NAPI_GRO_CB(skb)->flush = 0;
                NAPI_GRO_CB(skb)->free = 0;
+               NAPI_GRO_CB(skb)->udp_mark = 0;
  
                pp = ptype->callbacks.gro_receive(&napi->gro_list, skb);
                break;
        if (same_flow)
                goto ok;
  
-       if (NAPI_GRO_CB(skb)->flush || napi->gro_count >= MAX_GRO_SKBS)
+       if (NAPI_GRO_CB(skb)->flush)
                goto normal;
  
-       napi->gro_count++;
+       if (unlikely(napi->gro_count >= MAX_GRO_SKBS)) {
+               struct sk_buff *nskb = napi->gro_list;
+               /* locate the end of the list to select the 'oldest' flow */
+               while (nskb->next) {
+                       pp = &nskb->next;
+                       nskb = *pp;
+               }
+               *pp = NULL;
+               nskb->next = NULL;
+               napi_gro_complete(nskb);
+       } else {
+               napi->gro_count++;
+       }
        NAPI_GRO_CB(skb)->count = 1;
        NAPI_GRO_CB(skb)->age = jiffies;
        skb_shinfo(skb)->gso_size = skb_gro_len(skb);
@@@ -3915,12 -3972,39 +3972,39 @@@ normal
        goto pull;
  }
  
+ struct packet_offload *gro_find_receive_by_type(__be16 type)
+ {
+       struct list_head *offload_head = &offload_base;
+       struct packet_offload *ptype;
+       list_for_each_entry_rcu(ptype, offload_head, list) {
+               if (ptype->type != type || !ptype->callbacks.gro_receive)
+                       continue;
+               return ptype;
+       }
+       return NULL;
+ }
+ EXPORT_SYMBOL(gro_find_receive_by_type);
+ struct packet_offload *gro_find_complete_by_type(__be16 type)
+ {
+       struct list_head *offload_head = &offload_base;
+       struct packet_offload *ptype;
+       list_for_each_entry_rcu(ptype, offload_head, list) {
+               if (ptype->type != type || !ptype->callbacks.gro_complete)
+                       continue;
+               return ptype;
+       }
+       return NULL;
+ }
+ EXPORT_SYMBOL(gro_find_complete_by_type);
  
  static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
  {
        switch (ret) {
        case GRO_NORMAL:
-               if (netif_receive_skb(skb))
+               if (netif_receive_skb_internal(skb))
                        ret = GRO_DROP;
                break;
  
        return ret;
  }
  
- static void skb_gro_reset_offset(struct sk_buff *skb)
- {
-       const struct skb_shared_info *pinfo = skb_shinfo(skb);
-       const skb_frag_t *frag0 = &pinfo->frags[0];
-       NAPI_GRO_CB(skb)->data_offset = 0;
-       NAPI_GRO_CB(skb)->frag0 = NULL;
-       NAPI_GRO_CB(skb)->frag0_len = 0;
-       if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
-           pinfo->nr_frags &&
-           !PageHighMem(skb_frag_page(frag0))) {
-               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
-               NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
-       }
- }
  gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
  {
-       skb_gro_reset_offset(skb);
+       trace_napi_gro_receive_entry(skb);
  
        return napi_skb_finish(dev_gro_receive(napi, skb), skb);
  }
@@@ -3986,8 -4053,7 +4053,7 @@@ struct sk_buff *napi_get_frags(struct n
  
        if (!skb) {
                skb = netdev_alloc_skb_ip_align(napi->dev, GRO_MAX_HEAD);
-               if (skb)
-                       napi->skb = skb;
+               napi->skb = skb;
        }
        return skb;
  }
@@@ -3998,12 -4064,7 +4064,7 @@@ static gro_result_t napi_frags_finish(s
  {
        switch (ret) {
        case GRO_NORMAL:
-       case GRO_HELD:
-               skb->protocol = eth_type_trans(skb, skb->dev);
-               if (ret == GRO_HELD)
-                       skb_gro_pull(skb, -ETH_HLEN);
-               else if (netif_receive_skb(skb))
+               if (netif_receive_skb_internal(skb))
                        ret = GRO_DROP;
                break;
  
                napi_reuse_skb(napi, skb);
                break;
  
+       case GRO_HELD:
        case GRO_MERGED:
                break;
        }
  static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
  {
        struct sk_buff *skb = napi->skb;
-       struct ethhdr *eth;
-       unsigned int hlen;
-       unsigned int off;
  
        napi->skb = NULL;
  
-       skb_reset_mac_header(skb);
-       skb_gro_reset_offset(skb);
-       off = skb_gro_offset(skb);
-       hlen = off + sizeof(*eth);
-       eth = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               eth = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!eth)) {
-                       napi_reuse_skb(napi, skb);
-                       skb = NULL;
-                       goto out;
-               }
+       if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) {
+               napi_reuse_skb(napi, skb);
+               return NULL;
        }
+       skb->protocol = eth_type_trans(skb, skb->dev);
  
-       skb_gro_pull(skb, sizeof(*eth));
-       /*
-        * This works because the only protocols we care about don't require
-        * special handling.  We'll fix it up properly at the end.
-        */
-       skb->protocol = eth->h_proto;
- out:
        return skb;
  }
  
@@@ -4062,12 -4103,14 +4103,14 @@@ gro_result_t napi_gro_frags(struct napi
        if (!skb)
                return GRO_DROP;
  
+       trace_napi_gro_frags_entry(skb);
        return napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
  }
  EXPORT_SYMBOL(napi_gro_frags);
  
  /*
-  * net_rps_action sends any pending IPI's for rps.
+  * net_rps_action_and_irq_enable sends any pending IPI's for rps.
   * Note: called with local irq disabled, but exits with local irq enabled.
   */
  static void net_rps_action_and_irq_enable(struct softnet_data *sd)
@@@ -4272,17 -4315,10 +4315,10 @@@ EXPORT_SYMBOL(netif_napi_add)
  
  void netif_napi_del(struct napi_struct *napi)
  {
-       struct sk_buff *skb, *next;
        list_del_init(&napi->dev_list);
        napi_free_frags(napi);
  
-       for (skb = napi->gro_list; skb; skb = next) {
-               next = skb->next;
-               skb->next = NULL;
-               kfree_skb(skb);
-       }
+       kfree_skb_list(napi->gro_list);
        napi->gro_list = NULL;
        napi->gro_count = 0;
  }
@@@ -4399,19 -4435,6 +4435,6 @@@ struct netdev_adjacent 
        struct rcu_head rcu;
  };
  
- static struct netdev_adjacent *__netdev_find_adj_rcu(struct net_device *dev,
-                                                    struct net_device *adj_dev,
-                                                    struct list_head *adj_list)
- {
-       struct netdev_adjacent *adj;
-       list_for_each_entry_rcu(adj, adj_list, list) {
-               if (adj->dev == adj_dev)
-                       return adj;
-       }
-       return NULL;
- }
  static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev,
                                                 struct net_device *adj_dev,
                                                 struct list_head *adj_list)
@@@ -4450,13 -4473,12 +4473,12 @@@ EXPORT_SYMBOL(netdev_has_upper_dev)
   * Find out if a device is linked to an upper device and return true in case
   * it is. The caller must hold the RTNL lock.
   */
- bool netdev_has_any_upper_dev(struct net_device *dev)
static bool netdev_has_any_upper_dev(struct net_device *dev)
  {
        ASSERT_RTNL();
  
        return !list_empty(&dev->all_adj_list.upper);
  }
- EXPORT_SYMBOL(netdev_has_any_upper_dev);
  
  /**
   * netdev_master_upper_dev_get - Get master upper device
@@@ -4575,6 -4597,27 +4597,27 @@@ void *netdev_lower_get_next_private_rcu
  }
  EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
  
+ /**
+  * netdev_lower_get_first_private_rcu - Get the first ->private from the
+  *                                   lower neighbour list, RCU
+  *                                   variant
+  * @dev: device
+  *
+  * Gets the first netdev_adjacent->private from the dev's lower neighbour
+  * list. The caller must hold RCU read lock.
+  */
+ void *netdev_lower_get_first_private_rcu(struct net_device *dev)
+ {
+       struct netdev_adjacent *lower;
+       lower = list_first_or_null_rcu(&dev->adj_list.lower,
+                       struct netdev_adjacent, list);
+       if (lower)
+               return lower->private;
+       return NULL;
+ }
+ EXPORT_SYMBOL(netdev_lower_get_first_private_rcu);
  /**
   * netdev_master_upper_dev_get_rcu - Get master upper device
   * @dev: device
@@@ -4594,13 -4637,36 +4637,36 @@@ struct net_device *netdev_master_upper_
  }
  EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
  
+ int netdev_adjacent_sysfs_add(struct net_device *dev,
+                             struct net_device *adj_dev,
+                             struct list_head *dev_list)
+ {
+       char linkname[IFNAMSIZ+7];
+       sprintf(linkname, dev_list == &dev->adj_list.upper ?
+               "upper_%s" : "lower_%s", adj_dev->name);
+       return sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj),
+                                linkname);
+ }
+ void netdev_adjacent_sysfs_del(struct net_device *dev,
+                              char *name,
+                              struct list_head *dev_list)
+ {
+       char linkname[IFNAMSIZ+7];
+       sprintf(linkname, dev_list == &dev->adj_list.upper ?
+               "upper_%s" : "lower_%s", name);
+       sysfs_remove_link(&(dev->dev.kobj), linkname);
+ }
+ #define netdev_adjacent_is_neigh_list(dev, dev_list) \
+               (dev_list == &dev->adj_list.upper || \
+                dev_list == &dev->adj_list.lower)
  static int __netdev_adjacent_dev_insert(struct net_device *dev,
                                        struct net_device *adj_dev,
                                        struct list_head *dev_list,
                                        void *private, bool master)
  {
        struct netdev_adjacent *adj;
-       char linkname[IFNAMSIZ+7];
        int ret;
  
        adj = __netdev_find_adj(dev, adj_dev, dev_list);
        pr_debug("dev_hold for %s, because of link added from %s to %s\n",
                 adj_dev->name, dev->name, adj_dev->name);
  
-       if (dev_list == &dev->adj_list.lower) {
-               sprintf(linkname, "lower_%s", adj_dev->name);
-               ret = sysfs_create_link(&(dev->dev.kobj),
-                                       &(adj_dev->dev.kobj), linkname);
-               if (ret)
-                       goto free_adj;
-       } else if (dev_list == &dev->adj_list.upper) {
-               sprintf(linkname, "upper_%s", adj_dev->name);
-               ret = sysfs_create_link(&(dev->dev.kobj),
-                                       &(adj_dev->dev.kobj), linkname);
+       if (netdev_adjacent_is_neigh_list(dev, dev_list)) {
+               ret = netdev_adjacent_sysfs_add(dev, adj_dev, dev_list);
                if (ret)
                        goto free_adj;
        }
        return 0;
  
  remove_symlinks:
-       if (dev_list == &dev->adj_list.lower) {
-               sprintf(linkname, "lower_%s", adj_dev->name);
-               sysfs_remove_link(&(dev->dev.kobj), linkname);
-       } else if (dev_list == &dev->adj_list.upper) {
-               sprintf(linkname, "upper_%s", adj_dev->name);
-               sysfs_remove_link(&(dev->dev.kobj), linkname);
-       }
+       if (netdev_adjacent_is_neigh_list(dev, dev_list))
+               netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
  free_adj:
        kfree(adj);
        dev_put(adj_dev);
        return ret;
  }
  
- void __netdev_adjacent_dev_remove(struct net_device *dev,
-                                 struct net_device *adj_dev,
-                                 struct list_head *dev_list)
static void __netdev_adjacent_dev_remove(struct net_device *dev,
+                                        struct net_device *adj_dev,
+                                        struct list_head *dev_list)
  {
        struct netdev_adjacent *adj;
-       char linkname[IFNAMSIZ+7];
  
        adj = __netdev_find_adj(dev, adj_dev, dev_list);
  
        if (adj->master)
                sysfs_remove_link(&(dev->dev.kobj), "master");
  
-       if (dev_list == &dev->adj_list.lower) {
-               sprintf(linkname, "lower_%s", adj_dev->name);
-               sysfs_remove_link(&(dev->dev.kobj), linkname);
-       } else if (dev_list == &dev->adj_list.upper) {
-               sprintf(linkname, "upper_%s", adj_dev->name);
-               sysfs_remove_link(&(dev->dev.kobj), linkname);
-       }
+       if (netdev_adjacent_is_neigh_list(dev, dev_list))
+               netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
  
        list_del_rcu(&adj->list);
        pr_debug("dev_put for %s, because link removed from %s to %s\n",
        kfree_rcu(adj, rcu);
  }
  
- int __netdev_adjacent_dev_link_lists(struct net_device *dev,
-                                    struct net_device *upper_dev,
-                                    struct list_head *up_list,
-                                    struct list_head *down_list,
-                                    void *private, bool master)
static int __netdev_adjacent_dev_link_lists(struct net_device *dev,
+                                           struct net_device *upper_dev,
+                                           struct list_head *up_list,
+                                           struct list_head *down_list,
+                                           void *private, bool master)
  {
        int ret;
  
        return 0;
  }
  
- int __netdev_adjacent_dev_link(struct net_device *dev,
-                              struct net_device *upper_dev)
static int __netdev_adjacent_dev_link(struct net_device *dev,
+                                     struct net_device *upper_dev)
  {
        return __netdev_adjacent_dev_link_lists(dev, upper_dev,
                                                &dev->all_adj_list.upper,
                                                NULL, false);
  }
  
- void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
-                                       struct net_device *upper_dev,
-                                       struct list_head *up_list,
-                                       struct list_head *down_list)
static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
+                                              struct net_device *upper_dev,
+                                              struct list_head *up_list,
+                                              struct list_head *down_list)
  {
        __netdev_adjacent_dev_remove(dev, upper_dev, up_list);
        __netdev_adjacent_dev_remove(upper_dev, dev, down_list);
  }
  
- void __netdev_adjacent_dev_unlink(struct net_device *dev,
-                                 struct net_device *upper_dev)
static void __netdev_adjacent_dev_unlink(struct net_device *dev,
+                                        struct net_device *upper_dev)
  {
        __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
                                           &dev->all_adj_list.upper,
                                           &upper_dev->all_adj_list.lower);
  }
  
- int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
-                                        struct net_device *upper_dev,
-                                        void *private, bool master)
static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
+                                               struct net_device *upper_dev,
+                                               void *private, bool master)
  {
        int ret = __netdev_adjacent_dev_link(dev, upper_dev);
  
        return 0;
  }
  
- void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
-                                           struct net_device *upper_dev)
static void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
+                                                  struct net_device *upper_dev)
  {
        __netdev_adjacent_dev_unlink(dev, upper_dev);
        __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
@@@ -4967,20 -5013,24 +5013,24 @@@ void netdev_upper_dev_unlink(struct net
  }
  EXPORT_SYMBOL(netdev_upper_dev_unlink);
  
- void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
-                                      struct net_device *lower_dev)
+ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname)
  {
-       struct netdev_adjacent *lower;
+       struct netdev_adjacent *iter;
  
-       if (!lower_dev)
-               return NULL;
-       lower = __netdev_find_adj_rcu(dev, lower_dev, &dev->adj_list.lower);
-       if (!lower)
-               return NULL;
+       list_for_each_entry(iter, &dev->adj_list.upper, list) {
+               netdev_adjacent_sysfs_del(iter->dev, oldname,
+                                         &iter->dev->adj_list.lower);
+               netdev_adjacent_sysfs_add(iter->dev, dev,
+                                         &iter->dev->adj_list.lower);
+       }
  
-       return lower->private;
+       list_for_each_entry(iter, &dev->adj_list.lower, list) {
+               netdev_adjacent_sysfs_del(iter->dev, oldname,
+                                         &iter->dev->adj_list.upper);
+               netdev_adjacent_sysfs_add(iter->dev, dev,
+                                         &iter->dev->adj_list.upper);
+       }
  }
- EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu);
  
  void *netdev_lower_dev_get_private(struct net_device *dev,
                                   struct net_device *lower_dev)
@@@ -5314,6 -5364,17 +5364,17 @@@ int dev_change_flags(struct net_device 
  }
  EXPORT_SYMBOL(dev_change_flags);
  
+ static int __dev_set_mtu(struct net_device *dev, int new_mtu)
+ {
+       const struct net_device_ops *ops = dev->netdev_ops;
+       if (ops->ndo_change_mtu)
+               return ops->ndo_change_mtu(dev, new_mtu);
+       dev->mtu = new_mtu;
+       return 0;
+ }
  /**
   *    dev_set_mtu - Change maximum transfer unit
   *    @dev: device
   */
  int dev_set_mtu(struct net_device *dev, int new_mtu)
  {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       int err;
+       int err, orig_mtu;
  
        if (new_mtu == dev->mtu)
                return 0;
        if (!netif_device_present(dev))
                return -ENODEV;
  
-       err = 0;
-       if (ops->ndo_change_mtu)
-               err = ops->ndo_change_mtu(dev, new_mtu);
-       else
-               dev->mtu = new_mtu;
+       err = call_netdevice_notifiers(NETDEV_PRECHANGEMTU, dev);
+       err = notifier_to_errno(err);
+       if (err)
+               return err;
  
-       if (!err)
-               call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+       orig_mtu = dev->mtu;
+       err = __dev_set_mtu(dev, new_mtu);
+       if (!err) {
+               err = call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+               err = notifier_to_errno(err);
+               if (err) {
+                       /* setting mtu back and notifying everyone again,
+                        * so that they have a chance to revert changes.
+                        */
+                       __dev_set_mtu(dev, orig_mtu);
+                       call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+               }
+       }
        return err;
  }
  EXPORT_SYMBOL(dev_set_mtu);
@@@ -5697,7 -5768,7 +5768,7 @@@ void netif_stacked_transfer_operstate(c
  }
  EXPORT_SYMBOL(netif_stacked_transfer_operstate);
  
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
  static int netif_alloc_rx_queues(struct net_device *dev)
  {
        unsigned int i, count = dev->num_rx_queues;
@@@ -5836,13 -5907,8 +5907,8 @@@ int register_netdevice(struct net_devic
        dev->features |= NETIF_F_SOFT_FEATURES;
        dev->wanted_features = dev->features & dev->hw_features;
  
-       /* Turn on no cache copy if HW is doing checksum */
        if (!(dev->flags & IFF_LOOPBACK)) {
                dev->hw_features |= NETIF_F_NOCACHE_COPY;
-               if (dev->features & NETIF_F_ALL_CSUM) {
-                       dev->wanted_features |= NETIF_F_NOCACHE_COPY;
-                       dev->features |= NETIF_F_NOCACHE_COPY;
-               }
        }
  
        /* Make NETIF_F_HIGHDMA inheritable to VLAN devices.
@@@ -6229,7 -6295,7 +6295,7 @@@ void netdev_freemem(struct net_device *
   *    @rxqs:          the number of RX subqueues to allocate
   *
   *    Allocates a struct net_device with private data area for driver use
 - *    and performs basic initialization.  Also allocates subquue structs
 + *    and performs basic initialization.  Also allocates subqueue structs
   *    for each queue on the device.
   */
  struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
                return NULL;
        }
  
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
        if (rxqs < 1) {
                pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n");
                return NULL;
        if (netif_alloc_netdev_queues(dev))
                goto free_all;
  
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
        dev->num_rx_queues = rxqs;
        dev->real_num_rx_queues = rxqs;
        if (netif_alloc_rx_queues(dev))
@@@ -6323,7 -6389,7 +6389,7 @@@ free_all
  free_pcpu:
        free_percpu(dev->pcpu_refcnt);
        netif_free_tx_queues(dev);
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
        kfree(dev->_rx);
  #endif
  
@@@ -6348,7 -6414,7 +6414,7 @@@ void free_netdev(struct net_device *dev
        release_net(dev_net(dev));
  
        netif_free_tx_queues(dev);
- #ifdef CONFIG_RPS
+ #ifdef CONFIG_SYSFS
        kfree(dev->_rx);
  #endif
  
@@@ -6618,11 -6684,11 +6684,11 @@@ static int dev_cpu_callback(struct noti
  
        /* Process offline CPU's input_pkt_queue */
        while ((skb = __skb_dequeue(&oldsd->process_queue))) {
-               netif_rx(skb);
+               netif_rx_internal(skb);
                input_queue_head_incr(oldsd);
        }
        while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
-               netif_rx(skb);
+               netif_rx_internal(skb);
                input_queue_head_incr(oldsd);
        }
  
@@@ -6935,28 -7001,18 +7001,18 @@@ static int __init net_dev_init(void
        for_each_possible_cpu(i) {
                struct softnet_data *sd = &per_cpu(softnet_data, i);
  
-               memset(sd, 0, sizeof(*sd));
                skb_queue_head_init(&sd->input_pkt_queue);
                skb_queue_head_init(&sd->process_queue);
-               sd->completion_queue = NULL;
                INIT_LIST_HEAD(&sd->poll_list);
-               sd->output_queue = NULL;
                sd->output_queue_tailp = &sd->output_queue;
  #ifdef CONFIG_RPS
                sd->csd.func = rps_trigger_softirq;
                sd->csd.info = sd;
-               sd->csd.flags = 0;
                sd->cpu = i;
  #endif
  
                sd->backlog.poll = process_backlog;
                sd->backlog.weight = weight_p;
-               sd->backlog.gro_list = NULL;
-               sd->backlog.gro_count = 0;
- #ifdef CONFIG_NET_FLOW_LIMIT
-               sd->flow_limit = NULL;
- #endif
        }
  
        dev_boot_phase = 0;
index 56cbb69ba024a6564549d891dab2780a1ba86adf,1dda50c2e705dd6923d9e3758e2a8a0ff0971802..9043caedcd083bf48836d0a970d48d8c533f86ee
@@@ -30,7 -30,7 +30,7 @@@
  #define PRIOMAP_MIN_SZ                128
  
  /*
-  * Extend @dev->priomap so that it's large enough to accomodate
+  * Extend @dev->priomap so that it's large enough to accommodate
   * @target_idx.  @dev->priomap.priomap_len > @target_idx after successful
   * return.  Must be called under rtnl lock.
   */
@@@ -173,14 -173,14 +173,14 @@@ static u64 read_prioidx(struct cgroup_s
        return css->cgroup->id;
  }
  
 -static int read_priomap(struct cgroup_subsys_state *css, struct cftype *cft,
 -                      struct cgroup_map_cb *cb)
 +static int read_priomap(struct seq_file *sf, void *v)
  {
        struct net_device *dev;
  
        rcu_read_lock();
        for_each_netdev_rcu(&init_net, dev)
 -              cb->fill(cb, dev->name, netprio_prio(css, dev));
 +              seq_printf(sf, "%s %u\n", dev->name,
 +                         netprio_prio(seq_css(sf), dev));
        rcu_read_unlock();
        return 0;
  }
@@@ -238,7 -238,7 +238,7 @@@ static struct cftype ss_files[] = 
        },
        {
                .name = "ifpriomap",
 -              .read_map = read_priomap,
 +              .seq_show = read_priomap,
                .write_string = write_priomap,
        },
        { }     /* terminate */
diff --combined net/core/skbuff.c
index 0b5149c5bc4a14ca7ac559ab166961dacd2f1eec,15057d29b0105c730cb9af40591678ac522c0833..8f519dbb358b4b8ab8d2f497a000383fe7656341
@@@ -65,6 -65,7 +65,7 @@@
  #include <net/dst.h>
  #include <net/sock.h>
  #include <net/checksum.h>
+ #include <net/ip6_checksum.h>
  #include <net/xfrm.h>
  
  #include <asm/uaccess.h>
  struct kmem_cache *skbuff_head_cache __read_mostly;
  static struct kmem_cache *skbuff_fclone_cache __read_mostly;
  
 -static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
 -                                struct pipe_buffer *buf)
 -{
 -      put_page(buf->page);
 -}
 -
 -static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
 -                              struct pipe_buffer *buf)
 -{
 -      get_page(buf->page);
 -}
 -
 -static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
 -                             struct pipe_buffer *buf)
 -{
 -      return 1;
 -}
 -
 -
 -/* Pipe buffer operations for a socket. */
 -static const struct pipe_buf_operations sock_pipe_buf_ops = {
 -      .can_merge = 0,
 -      .map = generic_pipe_buf_map,
 -      .unmap = generic_pipe_buf_unmap,
 -      .confirm = generic_pipe_buf_confirm,
 -      .release = sock_pipe_buf_release,
 -      .steal = sock_pipe_buf_steal,
 -      .get = sock_pipe_buf_get,
 -};
 -
  /**
   *    skb_panic - private function for out-of-line support
   *    @skb:   buffer
@@@ -682,9 -713,8 +683,8 @@@ static void __copy_skb_header(struct sk
        new->inner_network_header = old->inner_network_header;
        new->inner_mac_header = old->inner_mac_header;
        skb_dst_copy(new, old);
-       new->rxhash             = old->rxhash;
+       skb_copy_hash(new, old);
        new->ooo_okay           = old->ooo_okay;
-       new->l4_rxhash          = old->l4_rxhash;
        new->no_fcs             = old->no_fcs;
        new->encapsulation      = old->encapsulation;
  #ifdef CONFIG_XFRM
@@@ -1800,7 -1830,7 +1800,7 @@@ int skb_splice_bits(struct sk_buff *skb
                .partial = partial,
                .nr_pages_max = MAX_SKB_FRAGS,
                .flags = flags,
 -              .ops = &sock_pipe_buf_ops,
 +              .ops = &nosteal_pipe_buf_ops,
                .spd_release = sock_spd_release,
        };
        struct sk_buff *frag_iter;
@@@ -2092,6 -2122,91 +2092,91 @@@ __wsum skb_copy_and_csum_bits(const str
  }
  EXPORT_SYMBOL(skb_copy_and_csum_bits);
  
+  /**
+  *    skb_zerocopy_headlen - Calculate headroom needed for skb_zerocopy()
+  *    @from: source buffer
+  *
+  *    Calculates the amount of linear headroom needed in the 'to' skb passed
+  *    into skb_zerocopy().
+  */
+ unsigned int
+ skb_zerocopy_headlen(const struct sk_buff *from)
+ {
+       unsigned int hlen = 0;
+       if (!from->head_frag ||
+           skb_headlen(from) < L1_CACHE_BYTES ||
+           skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
+               hlen = skb_headlen(from);
+       if (skb_has_frag_list(from))
+               hlen = from->len;
+       return hlen;
+ }
+ EXPORT_SYMBOL_GPL(skb_zerocopy_headlen);
+ /**
+  *    skb_zerocopy - Zero copy skb to skb
+  *    @to: destination buffer
+  *    @source: source buffer
+  *    @len: number of bytes to copy from source buffer
+  *    @hlen: size of linear headroom in destination buffer
+  *
+  *    Copies up to `len` bytes from `from` to `to` by creating references
+  *    to the frags in the source buffer.
+  *
+  *    The `hlen` as calculated by skb_zerocopy_headlen() specifies the
+  *    headroom in the `to` buffer.
+  */
+ void
+ skb_zerocopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
+ {
+       int i, j = 0;
+       int plen = 0; /* length of skb->head fragment */
+       struct page *page;
+       unsigned int offset;
+       BUG_ON(!from->head_frag && !hlen);
+       /* dont bother with small payloads */
+       if (len <= skb_tailroom(to)) {
+               skb_copy_bits(from, 0, skb_put(to, len), len);
+               return;
+       }
+       if (hlen) {
+               skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
+               len -= hlen;
+       } else {
+               plen = min_t(int, skb_headlen(from), len);
+               if (plen) {
+                       page = virt_to_head_page(from->head);
+                       offset = from->data - (unsigned char *)page_address(page);
+                       __skb_fill_page_desc(to, 0, page, offset, plen);
+                       get_page(page);
+                       j = 1;
+                       len -= plen;
+               }
+       }
+       to->truesize += len + plen;
+       to->len += len + plen;
+       to->data_len += len + plen;
+       for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
+               if (!len)
+                       break;
+               skb_shinfo(to)->frags[j] = skb_shinfo(from)->frags[i];
+               skb_shinfo(to)->frags[j].size = min_t(int, skb_shinfo(to)->frags[j].size, len);
+               len -= skb_shinfo(to)->frags[j].size;
+               skb_frag_ref(to, j);
+               j++;
+       }
+       skb_shinfo(to)->nr_frags = j;
+ }
+ EXPORT_SYMBOL_GPL(skb_zerocopy);
  void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
  {
        __wsum csum;
@@@ -2952,10 -3067,7 +3037,7 @@@ perform_csum_check
        return segs;
  
  err:
-       while ((skb = segs)) {
-               segs = skb->next;
-               kfree_skb(skb);
-       }
+       kfree_skb_list(segs);
        return ERR_PTR(err);
  }
  EXPORT_SYMBOL_GPL(skb_segment);
@@@ -3438,6 -3550,278 +3520,278 @@@ bool skb_partial_csum_set(struct sk_buf
  }
  EXPORT_SYMBOL_GPL(skb_partial_csum_set);
  
+ static int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len,
+                              unsigned int max)
+ {
+       if (skb_headlen(skb) >= len)
+               return 0;
+       /* If we need to pullup then pullup to the max, so we
+        * won't need to do it again.
+        */
+       if (max > skb->len)
+               max = skb->len;
+       if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL)
+               return -ENOMEM;
+       if (skb_headlen(skb) < len)
+               return -EPROTO;
+       return 0;
+ }
+ /* This value should be large enough to cover a tagged ethernet header plus
+  * maximally sized IP and TCP or UDP headers.
+  */
+ #define MAX_IP_HDR_LEN 128
+ static int skb_checksum_setup_ip(struct sk_buff *skb, bool recalculate)
+ {
+       unsigned int off;
+       bool fragment;
+       int err;
+       fragment = false;
+       err = skb_maybe_pull_tail(skb,
+                                 sizeof(struct iphdr),
+                                 MAX_IP_HDR_LEN);
+       if (err < 0)
+               goto out;
+       if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF))
+               fragment = true;
+       off = ip_hdrlen(skb);
+       err = -EPROTO;
+       if (fragment)
+               goto out;
+       switch (ip_hdr(skb)->protocol) {
+       case IPPROTO_TCP:
+               err = skb_maybe_pull_tail(skb,
+                                         off + sizeof(struct tcphdr),
+                                         MAX_IP_HDR_LEN);
+               if (err < 0)
+                       goto out;
+               if (!skb_partial_csum_set(skb, off,
+                                         offsetof(struct tcphdr, check))) {
+                       err = -EPROTO;
+                       goto out;
+               }
+               if (recalculate)
+                       tcp_hdr(skb)->check =
+                               ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+                                                  ip_hdr(skb)->daddr,
+                                                  skb->len - off,
+                                                  IPPROTO_TCP, 0);
+               break;
+       case IPPROTO_UDP:
+               err = skb_maybe_pull_tail(skb,
+                                         off + sizeof(struct udphdr),
+                                         MAX_IP_HDR_LEN);
+               if (err < 0)
+                       goto out;
+               if (!skb_partial_csum_set(skb, off,
+                                         offsetof(struct udphdr, check))) {
+                       err = -EPROTO;
+                       goto out;
+               }
+               if (recalculate)
+                       udp_hdr(skb)->check =
+                               ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+                                                  ip_hdr(skb)->daddr,
+                                                  skb->len - off,
+                                                  IPPROTO_UDP, 0);
+               break;
+       default:
+               goto out;
+       }
+       err = 0;
+ out:
+       return err;
+ }
+ /* This value should be large enough to cover a tagged ethernet header plus
+  * an IPv6 header, all options, and a maximal TCP or UDP header.
+  */
+ #define MAX_IPV6_HDR_LEN 256
+ #define OPT_HDR(type, skb, off) \
+       (type *)(skb_network_header(skb) + (off))
+ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
+ {
+       int err;
+       u8 nexthdr;
+       unsigned int off;
+       unsigned int len;
+       bool fragment;
+       bool done;
+       fragment = false;
+       done = false;
+       off = sizeof(struct ipv6hdr);
+       err = skb_maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN);
+       if (err < 0)
+               goto out;
+       nexthdr = ipv6_hdr(skb)->nexthdr;
+       len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
+       while (off <= len && !done) {
+               switch (nexthdr) {
+               case IPPROTO_DSTOPTS:
+               case IPPROTO_HOPOPTS:
+               case IPPROTO_ROUTING: {
+                       struct ipv6_opt_hdr *hp;
+                       err = skb_maybe_pull_tail(skb,
+                                                 off +
+                                                 sizeof(struct ipv6_opt_hdr),
+                                                 MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
+                       hp = OPT_HDR(struct ipv6_opt_hdr, skb, off);
+                       nexthdr = hp->nexthdr;
+                       off += ipv6_optlen(hp);
+                       break;
+               }
+               case IPPROTO_AH: {
+                       struct ip_auth_hdr *hp;
+                       err = skb_maybe_pull_tail(skb,
+                                                 off +
+                                                 sizeof(struct ip_auth_hdr),
+                                                 MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
+                       hp = OPT_HDR(struct ip_auth_hdr, skb, off);
+                       nexthdr = hp->nexthdr;
+                       off += ipv6_authlen(hp);
+                       break;
+               }
+               case IPPROTO_FRAGMENT: {
+                       struct frag_hdr *hp;
+                       err = skb_maybe_pull_tail(skb,
+                                                 off +
+                                                 sizeof(struct frag_hdr),
+                                                 MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
+                       hp = OPT_HDR(struct frag_hdr, skb, off);
+                       if (hp->frag_off & htons(IP6_OFFSET | IP6_MF))
+                               fragment = true;
+                       nexthdr = hp->nexthdr;
+                       off += sizeof(struct frag_hdr);
+                       break;
+               }
+               default:
+                       done = true;
+                       break;
+               }
+       }
+       err = -EPROTO;
+       if (!done || fragment)
+               goto out;
+       switch (nexthdr) {
+       case IPPROTO_TCP:
+               err = skb_maybe_pull_tail(skb,
+                                         off + sizeof(struct tcphdr),
+                                         MAX_IPV6_HDR_LEN);
+               if (err < 0)
+                       goto out;
+               if (!skb_partial_csum_set(skb, off,
+                                         offsetof(struct tcphdr, check))) {
+                       err = -EPROTO;
+                       goto out;
+               }
+               if (recalculate)
+                       tcp_hdr(skb)->check =
+                               ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                &ipv6_hdr(skb)->daddr,
+                                                skb->len - off,
+                                                IPPROTO_TCP, 0);
+               break;
+       case IPPROTO_UDP:
+               err = skb_maybe_pull_tail(skb,
+                                         off + sizeof(struct udphdr),
+                                         MAX_IPV6_HDR_LEN);
+               if (err < 0)
+                       goto out;
+               if (!skb_partial_csum_set(skb, off,
+                                         offsetof(struct udphdr, check))) {
+                       err = -EPROTO;
+                       goto out;
+               }
+               if (recalculate)
+                       udp_hdr(skb)->check =
+                               ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                &ipv6_hdr(skb)->daddr,
+                                                skb->len - off,
+                                                IPPROTO_UDP, 0);
+               break;
+       default:
+               goto out;
+       }
+       err = 0;
+ out:
+       return err;
+ }
+ /**
+  * skb_checksum_setup - set up partial checksum offset
+  * @skb: the skb to set up
+  * @recalculate: if true the pseudo-header checksum will be recalculated
+  */
+ int skb_checksum_setup(struct sk_buff *skb, bool recalculate)
+ {
+       int err;
+       switch (skb->protocol) {
+       case htons(ETH_P_IP):
+               err = skb_checksum_setup_ip(skb, recalculate);
+               break;
+       case htons(ETH_P_IPV6):
+               err = skb_checksum_setup_ipv6(skb, recalculate);
+               break;
+       default:
+               err = -EPROTO;
+               break;
+       }
+       return err;
+ }
+ EXPORT_SYMBOL(skb_checksum_setup);
  void __skb_warn_lro_forwarding(const struct sk_buff *skb)
  {
        net_warn_ratelimited("%s: received packets cannot be forwarded while LRO is enabled\n",
diff --combined net/ipv4/tcp.c
index 82de786036860d298d63c2184de004f69901156b,e2a40515e66593660e1002cf20f6fc0d3969af14..4475b3bb494d5d126dd844b0159629cd672afbdc
@@@ -285,6 -285,8 +285,8 @@@ int sysctl_tcp_fin_timeout __read_mostl
  
  int sysctl_tcp_min_tso_segs __read_mostly = 2;
  
+ int sysctl_tcp_autocorking __read_mostly = 1;
  struct percpu_counter tcp_orphan_count;
  EXPORT_SYMBOL_GPL(tcp_orphan_count);
  
@@@ -379,7 -381,7 +381,7 @@@ void tcp_init_sock(struct sock *sk
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
  
-       skb_queue_head_init(&tp->out_of_order_queue);
+       __skb_queue_head_init(&tp->out_of_order_queue);
        tcp_init_xmit_timers(sk);
        tcp_prequeue_init(tp);
        INIT_LIST_HEAD(&tp->tsq_node);
@@@ -619,19 -621,58 +621,58 @@@ static inline void tcp_mark_urg(struct 
                tp->snd_up = tp->write_seq;
  }
  
- static inline void tcp_push(struct sock *sk, int flags, int mss_now,
-                           int nonagle)
+ /* If a not yet filled skb is pushed, do not send it if
+  * we have data packets in Qdisc or NIC queues :
+  * Because TX completion will happen shortly, it gives a chance
+  * to coalesce future sendmsg() payload into this skb, without
+  * need for a timer, and with no latency trade off.
+  * As packets containing data payload have a bigger truesize
+  * than pure acks (dataless) packets, the last checks prevent
+  * autocorking if we only have an ACK in Qdisc/NIC queues,
+  * or if TX completion was delayed after we processed ACK packet.
+  */
+ static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb,
+                               int size_goal)
  {
-       if (tcp_send_head(sk)) {
-               struct tcp_sock *tp = tcp_sk(sk);
+       return skb->len < size_goal &&
+              sysctl_tcp_autocorking &&
+              skb != tcp_write_queue_head(sk) &&
+              atomic_read(&sk->sk_wmem_alloc) > skb->truesize;
+ }
+ static void tcp_push(struct sock *sk, int flags, int mss_now,
+                    int nonagle, int size_goal)
+ {
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct sk_buff *skb;
  
-               if (!(flags & MSG_MORE) || forced_push(tp))
-                       tcp_mark_push(tp, tcp_write_queue_tail(sk));
+       if (!tcp_send_head(sk))
+               return;
  
-               tcp_mark_urg(tp, flags);
-               __tcp_push_pending_frames(sk, mss_now,
-                                         (flags & MSG_MORE) ? TCP_NAGLE_CORK : nonagle);
+       skb = tcp_write_queue_tail(sk);
+       if (!(flags & MSG_MORE) || forced_push(tp))
+               tcp_mark_push(tp, skb);
+       tcp_mark_urg(tp, flags);
+       if (tcp_should_autocork(sk, skb, size_goal)) {
+               /* avoid atomic op if TSQ_THROTTLED bit is already set */
+               if (!test_bit(TSQ_THROTTLED, &tp->tsq_flags)) {
+                       NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTOCORKING);
+                       set_bit(TSQ_THROTTLED, &tp->tsq_flags);
+               }
+               /* It is possible TX completion already happened
+                * before we set TSQ_THROTTLED.
+                */
+               if (atomic_read(&sk->sk_wmem_alloc) > skb->truesize)
+                       return;
        }
+       if (flags & MSG_MORE)
+               nonagle = TCP_NAGLE_CORK;
+       __tcp_push_pending_frames(sk, mss_now, nonagle);
  }
  
  static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
@@@ -934,7 -975,8 +975,8 @@@ new_segment
  wait_for_sndbuf:
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
  wait_for_memory:
-               tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+               tcp_push(sk, flags & ~MSG_MORE, mss_now,
+                        TCP_NAGLE_PUSH, size_goal);
  
                if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
                        goto do_error;
  
  out:
        if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
-               tcp_push(sk, flags, mss_now, tp->nonagle);
+               tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
        return copied;
  
  do_error:
@@@ -1225,7 -1267,8 +1267,8 @@@ wait_for_sndbuf
                        set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
  wait_for_memory:
                        if (copied)
-                               tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+                               tcp_push(sk, flags & ~MSG_MORE, mss_now,
+                                        TCP_NAGLE_PUSH, size_goal);
  
                        if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
                                goto do_error;
  
  out:
        if (copied)
-               tcp_push(sk, flags, mss_now, tp->nonagle);
+               tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
        release_sock(sk);
        return copied + copied_syn;
  
@@@ -1623,11 -1666,11 +1666,11 @@@ int tcp_recvmsg(struct kiocb *iocb, str
                    (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
                    !sysctl_tcp_low_latency &&
                    net_dma_find_channel()) {
 -                      preempt_enable_no_resched();
 +                      preempt_enable();
                        tp->ucopy.pinned_list =
                                        dma_pin_iovec_pages(msg->msg_iov, len);
                } else {
 -                      preempt_enable_no_resched();
 +                      preempt_enable();
                }
        }
  #endif
diff --combined net/nfc/digital_dep.c
index 8b362e802d2ffbb6587ee166cc7b585cc0c1af77,43e450f78d0a2dd034335cf5d3384ccd86940187..d4ed25ff723fd9ace06d03444d7fcc3f9b3b6b27
@@@ -32,7 -32,6 +32,6 @@@
  #define DIGITAL_ATR_REQ_MIN_SIZE 16
  #define DIGITAL_ATR_REQ_MAX_SIZE 64
  
- #define DIGITAL_NFCID3_LEN ((u8)8)
  #define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
  #define DIGITAL_GB_BIT        0x02
  
@@@ -206,10 -205,9 +205,9 @@@ int digital_in_send_atr_req(struct nfc_
        atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
        atr_req->cmd = DIGITAL_CMD_ATR_REQ;
        if (target->nfcid2_len)
-               memcpy(atr_req->nfcid3, target->nfcid2,
-                      max(target->nfcid2_len, DIGITAL_NFCID3_LEN));
+               memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
        else
-               get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN);
+               get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
  
        atr_req->did = 0;
        atr_req->bs = 0;
@@@ -382,6 -380,33 +380,33 @@@ int digital_in_send_dep_req(struct nfc_
                                   data_exch);
  }
  
+ static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
+ {
+       ddev->curr_rf_tech = rf_tech;
+       ddev->skb_add_crc = digital_skb_add_crc_none;
+       ddev->skb_check_crc = digital_skb_check_crc_none;
+       if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
+               return;
+       switch (ddev->curr_rf_tech) {
+       case NFC_DIGITAL_RF_TECH_106A:
+               ddev->skb_add_crc = digital_skb_add_crc_a;
+               ddev->skb_check_crc = digital_skb_check_crc_a;
+               break;
+       case NFC_DIGITAL_RF_TECH_212F:
+       case NFC_DIGITAL_RF_TECH_424F:
+               ddev->skb_add_crc = digital_skb_add_crc_f;
+               ddev->skb_check_crc = digital_skb_check_crc_f;
+               break;
+       default:
+               break;
+       }
+ }
  static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
                                    struct sk_buff *resp)
  {
@@@ -472,11 -497,13 +497,13 @@@ int digital_tg_send_dep_res(struct nfc_
  static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
                                             void *arg, struct sk_buff *resp)
  {
-       u8 rf_tech = PTR_ERR(arg);
+       u8 rf_tech = (unsigned long)arg;
  
        if (IS_ERR(resp))
                return;
  
+       digital_tg_set_rf_tech(ddev, rf_tech);
        digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
  
        digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
@@@ -508,7 -535,7 +535,7 @@@ static int digital_tg_send_psl_res(stru
        ddev->skb_add_crc(skb);
  
        rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
-                                ERR_PTR(rf_tech));
+                                (void *)(unsigned long)rf_tech);
  
        if (rc)
                kfree_skb(skb);
@@@ -563,7 -590,7 +590,7 @@@ static void digital_tg_recv_psl_req(str
                rf_tech = NFC_DIGITAL_RF_TECH_424F;
                break;
        default:
 -              pr_err("Unsuported dsi value %d\n", dsi);
 +              pr_err("Unsupported dsi value %d\n", dsi);
                goto exit;
        }
  
@@@ -661,16 -688,10 +688,10 @@@ void digital_tg_recv_atr_req(struct nfc
  
        if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
                min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
-               ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_106A;
-               ddev->skb_add_crc = digital_skb_add_crc_a;
-               ddev->skb_check_crc = digital_skb_check_crc_a;
+               digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
        } else {
                min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
-               ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_212F;
-               ddev->skb_add_crc = digital_skb_add_crc_f;
-               ddev->skb_check_crc = digital_skb_check_crc_f;
+               digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
        }
  
        if (resp->len < min_size) {
                goto exit;
        }
  
-       if (DIGITAL_DRV_CAPS_TG_CRC(ddev)) {
-               ddev->skb_add_crc = digital_skb_add_crc_none;
-               ddev->skb_check_crc = digital_skb_check_crc_none;
-       }
+       ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
  
        rc = ddev->skb_check_crc(resp);
        if (rc) {
diff --combined net/xfrm/xfrm_policy.c
index 0d49945d0b9eed2910d39a3485c3ad0c79166d87,01770826a15ad37b03a49e74e4118af5ed8c2f44..4b98b25793c5c23fa1799463b45ad71a030fceb9
  #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
  #define XFRM_MAX_QUEUE_LEN    100
  
- DEFINE_MUTEX(xfrm_cfg_mutex);
- EXPORT_SYMBOL(xfrm_cfg_mutex);
- static DEFINE_SPINLOCK(xfrm_policy_sk_bundle_lock);
  static struct dst_entry *xfrm_policy_sk_bundles;
- static DEFINE_RWLOCK(xfrm_policy_lock);
  
  static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock);
  static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO]
@@@ -176,7 -171,7 +171,7 @@@ static inline unsigned long make_jiffie
  
  static void xfrm_policy_timer(unsigned long data)
  {
-       struct xfrm_policy *xp = (struct xfrm_policy*)data;
+       struct xfrm_policy *xp = (struct xfrm_policy *)data;
        unsigned long now = get_seconds();
        long next = LONG_MAX;
        int warn = 0;
@@@ -438,7 -433,7 +433,7 @@@ static void xfrm_bydst_resize(struct ne
        if (!ndst)
                return;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
  
        for (i = hmask; i >= 0; i--)
                xfrm_dst_hash_transfer(odst + i, ndst, nhashmask);
        net->xfrm.policy_bydst[dir].table = ndst;
        net->xfrm.policy_bydst[dir].hmask = nhashmask;
  
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head));
  }
@@@ -463,7 -458,7 +458,7 @@@ static void xfrm_byidx_resize(struct ne
        if (!nidx)
                return;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
  
        for (i = hmask; i >= 0; i--)
                xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask);
        net->xfrm.policy_byidx = nidx;
        net->xfrm.policy_idx_hmask = nhashmask;
  
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        xfrm_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head));
  }
@@@ -504,7 -499,7 +499,7 @@@ static inline int xfrm_byidx_should_res
  
  void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si)
  {
-       read_lock_bh(&xfrm_policy_lock);
+       read_lock_bh(&net->xfrm.xfrm_policy_lock);
        si->incnt = net->xfrm.policy_count[XFRM_POLICY_IN];
        si->outcnt = net->xfrm.policy_count[XFRM_POLICY_OUT];
        si->fwdcnt = net->xfrm.policy_count[XFRM_POLICY_FWD];
        si->fwdscnt = net->xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX];
        si->spdhcnt = net->xfrm.policy_idx_hmask;
        si->spdhmcnt = xfrm_policy_hashmax;
-       read_unlock_bh(&xfrm_policy_lock);
+       read_unlock_bh(&net->xfrm.xfrm_policy_lock);
  }
  EXPORT_SYMBOL(xfrm_spd_getinfo);
  
@@@ -538,7 -533,7 +533,7 @@@ static void xfrm_hash_resize(struct wor
  
  /* Generate new index... KAME seems to generate them ordered by cost
   * of an absolute inpredictability of ordering of rules. This will not pass. */
- static u32 xfrm_gen_index(struct net *net, int dir)
+ static u32 xfrm_gen_index(struct net *net, int dir, u32 index)
  {
        static u32 idx_generator;
  
                u32 idx;
                int found;
  
-               idx = (idx_generator | dir);
-               idx_generator += 8;
+               if (!index) {
+                       idx = (idx_generator | dir);
+                       idx_generator += 8;
+               } else {
+                       idx = index;
+                       index = 0;
+               }
                if (idx == 0)
                        idx = 8;
                list = net->xfrm.policy_byidx + idx_hash(net, idx);
@@@ -630,7 -631,7 +631,7 @@@ int xfrm_policy_insert(int dir, struct 
        struct hlist_head *chain;
        struct hlist_node *newpos;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
        delpol = NULL;
        newpos = NULL;
                    xfrm_sec_ctx_match(pol->security, policy->security) &&
                    !WARN_ON(delpol)) {
                        if (excl) {
-                               write_unlock_bh(&xfrm_policy_lock);
+                               write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                                return -EEXIST;
                        }
                        delpol = pol;
                xfrm_policy_requeue(delpol, policy);
                __xfrm_policy_unlink(delpol, dir);
        }
-       policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
+       policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index);
        hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
        policy->curlft.add_time = get_seconds();
        policy->curlft.use_time = 0;
        if (!mod_timer(&policy->timer, jiffies + HZ))
                xfrm_pol_hold(policy);
        list_add(&policy->walk.all, &net->xfrm.policy_all);
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        if (delpol)
                xfrm_policy_kill(delpol);
@@@ -699,7 -700,7 +700,7 @@@ struct xfrm_policy *xfrm_policy_bysel_c
        struct hlist_head *chain;
  
        *err = 0;
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = policy_hash_bysel(net, sel, sel->family, dir);
        ret = NULL;
        hlist_for_each_entry(pol, chain, bydst) {
                                *err = security_xfrm_policy_delete(
                                                                pol->security);
                                if (*err) {
-                                       write_unlock_bh(&xfrm_policy_lock);
+                                       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                                        return pol;
                                }
                                __xfrm_policy_unlink(pol, dir);
                        break;
                }
        }
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        if (ret && delete)
                xfrm_policy_kill(ret);
@@@ -740,7 -741,7 +741,7 @@@ struct xfrm_policy *xfrm_policy_byid(st
                return NULL;
  
        *err = 0;
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = net->xfrm.policy_byidx + idx_hash(net, id);
        ret = NULL;
        hlist_for_each_entry(pol, chain, byidx) {
                                *err = security_xfrm_policy_delete(
                                                                pol->security);
                                if (*err) {
-                                       write_unlock_bh(&xfrm_policy_lock);
+                                       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                                        return pol;
                                }
                                __xfrm_policy_unlink(pol, dir);
                        break;
                }
        }
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        if (ret && delete)
                xfrm_policy_kill(ret);
@@@ -823,7 -824,7 +824,7 @@@ int xfrm_policy_flush(struct net *net, 
  {
        int dir, err = 0, cnt = 0;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
  
        err = xfrm_policy_flush_secctx_check(net, type, audit_info);
        if (err)
                        if (pol->type != type)
                                continue;
                        __xfrm_policy_unlink(pol, dir);
-                       write_unlock_bh(&xfrm_policy_lock);
+                       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                        cnt++;
  
                        xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
  
                        xfrm_policy_kill(pol);
  
-                       write_lock_bh(&xfrm_policy_lock);
+                       write_lock_bh(&net->xfrm.xfrm_policy_lock);
                        goto again1;
                }
  
                                if (pol->type != type)
                                        continue;
                                __xfrm_policy_unlink(pol, dir);
-                               write_unlock_bh(&xfrm_policy_lock);
+                               write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                                cnt++;
  
                                xfrm_audit_policy_delete(pol, 1,
                                                         audit_info->secid);
                                xfrm_policy_kill(pol);
  
-                               write_lock_bh(&xfrm_policy_lock);
+                               write_lock_bh(&net->xfrm.xfrm_policy_lock);
                                goto again2;
                        }
                }
        if (!cnt)
                err = -ESRCH;
  out:
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
        return err;
  }
  EXPORT_SYMBOL(xfrm_policy_flush);
@@@ -898,7 -899,7 +899,7 @@@ int xfrm_policy_walk(struct net *net, s
        if (list_empty(&walk->walk.all) && walk->seq != 0)
                return 0;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        if (list_empty(&walk->walk.all))
                x = list_first_entry(&net->xfrm.policy_all, struct xfrm_policy_walk_entry, all);
        else
        }
        list_del_init(&walk->walk.all);
  out:
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
        return error;
  }
  EXPORT_SYMBOL(xfrm_policy_walk);
@@@ -938,14 -939,14 +939,14 @@@ void xfrm_policy_walk_init(struct xfrm_
  }
  EXPORT_SYMBOL(xfrm_policy_walk_init);
  
- void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
+ void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net)
  {
        if (list_empty(&walk->walk.all))
                return;
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME where is net? */
        list_del(&walk->walk.all);
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  }
  EXPORT_SYMBOL(xfrm_policy_walk_done);
  
@@@ -990,7 -991,7 +991,7 @@@ static struct xfrm_policy *xfrm_policy_
        if (unlikely(!daddr || !saddr))
                return NULL;
  
-       read_lock_bh(&xfrm_policy_lock);
+       read_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = policy_hash_direct(net, daddr, saddr, family, dir);
        ret = NULL;
        hlist_for_each_entry(pol, chain, bydst) {
        if (ret)
                xfrm_pol_hold(ret);
  fail:
-       read_unlock_bh(&xfrm_policy_lock);
+       read_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        return ret;
  }
@@@ -1103,8 -1104,9 +1104,9 @@@ static struct xfrm_policy *xfrm_sk_poli
                                                 const struct flowi *fl)
  {
        struct xfrm_policy *pol;
+       struct net *net = sock_net(sk);
  
-       read_lock_bh(&xfrm_policy_lock);
+       read_lock_bh(&net->xfrm.xfrm_policy_lock);
        if ((pol = sk->sk_policy[dir]) != NULL) {
                bool match = xfrm_selector_match(&pol->selector, fl,
                                                 sk->sk_family);
                        pol = NULL;
        }
  out:
-       read_unlock_bh(&xfrm_policy_lock);
+       read_unlock_bh(&net->xfrm.xfrm_policy_lock);
        return pol;
  }
  
@@@ -1166,9 -1168,11 +1168,11 @@@ static struct xfrm_policy *__xfrm_polic
  
  int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
  {
-       write_lock_bh(&xfrm_policy_lock);
+       struct net *net = xp_net(pol);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        pol = __xfrm_policy_unlink(pol, dir);
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
        if (pol) {
                xfrm_policy_kill(pol);
                return 0;
@@@ -1187,12 -1191,12 +1191,12 @@@ int xfrm_sk_policy_insert(struct sock *
                return -EINVAL;
  #endif
  
-       write_lock_bh(&xfrm_policy_lock);
+       write_lock_bh(&net->xfrm.xfrm_policy_lock);
        old_pol = sk->sk_policy[dir];
        sk->sk_policy[dir] = pol;
        if (pol) {
                pol->curlft.add_time = get_seconds();
-               pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
+               pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0);
                __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
        }
        if (old_pol) {
                 */
                __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
        }
-       write_unlock_bh(&xfrm_policy_lock);
+       write_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        if (old_pol) {
                xfrm_policy_kill(old_pol);
  static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
  {
        struct xfrm_policy *newp = xfrm_policy_alloc(xp_net(old), GFP_ATOMIC);
+       struct net *net = xp_net(old);
  
        if (newp) {
                newp->selector = old->selector;
                newp->type = old->type;
                memcpy(newp->xfrm_vec, old->xfrm_vec,
                       newp->xfrm_nr*sizeof(struct xfrm_tmpl));
-               write_lock_bh(&xfrm_policy_lock);
+               write_lock_bh(&net->xfrm.xfrm_policy_lock);
                __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir);
-               write_unlock_bh(&xfrm_policy_lock);
+               write_unlock_bh(&net->xfrm.xfrm_policy_lock);
                xfrm_pol_put(newp);
        }
        return newp;
@@@ -1281,7 -1286,7 +1286,7 @@@ xfrm_tmpl_resolve_one(struct xfrm_polic
        xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
        xfrm_address_t tmp;
  
-       for (nx=0, i = 0; i < policy->xfrm_nr; i++) {
+       for (nx = 0, i = 0; i < policy->xfrm_nr; i++) {
                struct xfrm_state *x;
                xfrm_address_t *remote = daddr;
                xfrm_address_t *local  = saddr;
                        error = (x->km.state == XFRM_STATE_ERROR ?
                                 -EINVAL : -EAGAIN);
                        xfrm_state_put(x);
-               }
-               else if (error == -ESRCH)
+               } else if (error == -ESRCH) {
                        error = -EAGAIN;
+               }
  
                if (!tmpl->optional)
                        goto fail;
        return nx;
  
  fail:
-       for (nx--; nx>=0; nx--)
+       for (nx--; nx >= 0; nx--)
                xfrm_state_put(xfrm[nx]);
        return error;
  }
@@@ -1358,7 -1363,7 +1363,7 @@@ xfrm_tmpl_resolve(struct xfrm_policy **
        return cnx;
  
   fail:
-       for (cnx--; cnx>=0; cnx--)
+       for (cnx--; cnx >= 0; cnx--)
                xfrm_state_put(tpp[cnx]);
        return error;
  
@@@ -1636,20 -1641,22 +1641,22 @@@ free_dst
        goto out;
  }
  
- static int inline
- xfrm_dst_alloc_copy(void **target, const void *src, int size)
+ #ifdef CONFIG_XFRM_SUB_POLICY
static int xfrm_dst_alloc_copy(void **target, const void *src, int size)
  {
        if (!*target) {
                *target = kmalloc(size, GFP_ATOMIC);
                if (!*target)
                        return -ENOMEM;
        }
        memcpy(*target, src, size);
        return 0;
  }
+ #endif
  
- static int inline
xfrm_dst_update_parent(struct dst_entry *dst, const struct xfrm_selector *sel)
+ static int xfrm_dst_update_parent(struct dst_entry *dst,
                                const struct xfrm_selector *sel)
  {
  #ifdef CONFIG_XFRM_SUB_POLICY
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
  #endif
  }
  
- static int inline
xfrm_dst_update_origin(struct dst_entry *dst, const struct flowi *fl)
+ static int xfrm_dst_update_origin(struct dst_entry *dst,
                                const struct flowi *fl)
  {
  #ifdef CONFIG_XFRM_SUB_POLICY
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
@@@ -1699,7 -1706,7 +1706,7 @@@ static int xfrm_expand_policies(const s
                                xfrm_pols_put(pols, *num_pols);
                                return PTR_ERR(pols[1]);
                        }
-                       (*num_pols) ++;
+                       (*num_pols)++;
                        (*num_xfrms) += pols[1]->xfrm_nr;
                }
        }
@@@ -1753,7 -1760,7 +1760,7 @@@ xfrm_resolve_and_create_bundle(struct x
        }
  
        xdst->num_pols = num_pols;
-       memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
+       memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
        xdst->policy_genid = atomic_read(&pols[0]->genid);
  
        return xdst;
@@@ -1896,8 -1903,7 +1903,7 @@@ static struct xfrm_dst *xfrm_create_dum
        if (IS_ERR(xdst))
                return xdst;
  
-       if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0 ||
-           (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP))
+       if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0)
                return xdst;
  
        dst1 = &xdst->u.dst;
@@@ -2023,7 -2029,7 +2029,7 @@@ make_dummy_bundle
        }
        xdst->num_pols = num_pols;
        xdst->num_xfrms = num_xfrms;
-       memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
+       memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
  
        dst_hold(&xdst->u.dst);
        return &xdst->flo;
@@@ -2072,7 -2078,6 +2078,6 @@@ struct dst_entry *xfrm_lookup(struct ne
        u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
        int i, err, num_pols, num_xfrms = 0, drop_pols = 0;
  
- restart:
        dst = NULL;
        xdst = NULL;
        route = NULL;
  
                        dst_hold(&xdst->u.dst);
  
-                       spin_lock_bh(&xfrm_policy_sk_bundle_lock);
+                       spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
                        xdst->u.dst.next = xfrm_policy_sk_bundles;
                        xfrm_policy_sk_bundles = &xdst->u.dst;
-                       spin_unlock_bh(&xfrm_policy_sk_bundle_lock);
+                       spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
  
                        route = xdst->route;
                }
  
                num_pols = xdst->num_pols;
                num_xfrms = xdst->num_xfrms;
-               memcpy(pols, xdst->pols, sizeof(struct xfrm_policy*) * num_pols);
+               memcpy(pols, xdst->pols, sizeof(struct xfrm_policy *) * num_pols);
                route = xdst->route;
        }
  
  
                        return make_blackhole(net, family, dst_orig);
                }
-               if (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP) {
-                       DECLARE_WAITQUEUE(wait, current);
  
-                       add_wait_queue(&net->xfrm.km_waitq, &wait);
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule();
-                       set_current_state(TASK_RUNNING);
-                       remove_wait_queue(&net->xfrm.km_waitq, &wait);
-                       if (!signal_pending(current)) {
-                               dst_release(dst);
-                               goto restart;
-                       }
-                       err = -ERESTART;
-               } else
-                       err = -EAGAIN;
+               err = -EAGAIN;
  
                XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
                goto error;
@@@ -2344,7 -2334,7 +2334,7 @@@ int __xfrm_policy_check(struct sock *sk
        if (skb->sp) {
                int i;
  
-               for (i=skb->sp->len-1; i>=0; i--) {
+               for (i = skb->sp->len-1; i >= 0; i--) {
                        struct xfrm_state *x = skb->sp->xvec[i];
                        if (!xfrm_selector_match(&x->sel, &fl, family)) {
                                XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
        pol->curlft.use_time = get_seconds();
  
        pols[0] = pol;
-       npols ++;
+       npols++;
  #ifdef CONFIG_XFRM_SUB_POLICY
        if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
                pols[1] = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN,
                                return 0;
                        }
                        pols[1]->curlft.use_time = get_seconds();
-                       npols ++;
+                       npols++;
                }
        }
  #endif
                }
                xfrm_nr = ti;
                if (npols > 1) {
-                       xfrm_tmpl_sort(stp, tpp, xfrm_nr, family);
+                       xfrm_tmpl_sort(stp, tpp, xfrm_nr, family, net);
                        tpp = stp;
                }
  
@@@ -2563,10 -2553,10 +2553,10 @@@ static void __xfrm_garbage_collect(stru
  {
        struct dst_entry *head, *next;
  
-       spin_lock_bh(&xfrm_policy_sk_bundle_lock);
+       spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
        head = xfrm_policy_sk_bundles;
        xfrm_policy_sk_bundles = NULL;
-       spin_unlock_bh(&xfrm_policy_sk_bundle_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
  
        while (head) {
                next = head->next;
@@@ -2906,12 -2896,12 +2896,12 @@@ static void xfrm_policy_fini(struct ne
        flush_work(&net->xfrm.policy_hash_work);
  #ifdef CONFIG_XFRM_SUB_POLICY
        audit_info.loginuid = INVALID_UID;
 -      audit_info.sessionid = -1;
 +      audit_info.sessionid = (unsigned int)-1;
        audit_info.secid = 0;
        xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info);
  #endif
        audit_info.loginuid = INVALID_UID;
 -      audit_info.sessionid = -1;
 +      audit_info.sessionid = (unsigned int)-1;
        audit_info.secid = 0;
        xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
  
@@@ -2950,6 -2940,13 +2940,13 @@@ static int __net_init xfrm_net_init(str
        rv = xfrm_sysctl_init(net);
        if (rv < 0)
                goto out_sysctl;
+       /* Initialize the per-net locks here */
+       spin_lock_init(&net->xfrm.xfrm_state_lock);
+       rwlock_init(&net->xfrm.xfrm_policy_lock);
+       spin_lock_init(&net->xfrm.xfrm_policy_sk_bundle_lock);
+       mutex_init(&net->xfrm.xfrm_cfg_mutex);
        return 0;
  
  out_sysctl:
@@@ -2992,7 -2989,7 +2989,7 @@@ static void xfrm_audit_common_policyinf
                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
                                 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
  
-       switch(sel->family) {
+       switch (sel->family) {
        case AF_INET:
                audit_log_format(audit_buf, " src=%pI4", &sel->saddr.a4);
                if (sel->prefixlen_s != 32)
  }
  
  void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
 -                         kuid_t auid, u32 sessionid, u32 secid)
 +                         kuid_t auid, unsigned int sessionid, u32 secid)
  {
        struct audit_buffer *audit_buf;
  
  EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
  
  void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
 -                            kuid_t auid, u32 sessionid, u32 secid)
 +                            kuid_t auid, unsigned int sessionid, u32 secid)
  {
        struct audit_buffer *audit_buf;
  
@@@ -3069,15 -3066,15 +3066,15 @@@ static bool xfrm_migrate_selector_match
        return false;
  }
  
- static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel,
-                                                    u8 dir, u8 type)
+ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
+                                                   u8 dir, u8 type, struct net *net)
  {
        struct xfrm_policy *pol, *ret = NULL;
        struct hlist_head *chain;
        u32 priority = ~0U;
  
-       read_lock_bh(&xfrm_policy_lock);
-       chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir);
+       read_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME*/
+       chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
        hlist_for_each_entry(pol, chain, bydst) {
                if (xfrm_migrate_selector_match(sel, &pol->selector) &&
                    pol->type == type) {
                        break;
                }
        }
-       chain = &init_net.xfrm.policy_inexact[dir];
+       chain = &net->xfrm.policy_inexact[dir];
        hlist_for_each_entry(pol, chain, bydst) {
                if (xfrm_migrate_selector_match(sel, &pol->selector) &&
                    pol->type == type &&
        if (ret)
                xfrm_pol_hold(ret);
  
-       read_unlock_bh(&xfrm_policy_lock);
+       read_unlock_bh(&net->xfrm.xfrm_policy_lock);
  
        return ret;
  }
@@@ -3210,7 -3207,7 +3207,7 @@@ static int xfrm_migrate_check(const str
  
  int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
                 struct xfrm_migrate *m, int num_migrate,
-                struct xfrm_kmaddress *k)
+                struct xfrm_kmaddress *k, struct net *net)
  {
        int i, err, nx_cur = 0, nx_new = 0;
        struct xfrm_policy *pol = NULL;
                goto out;
  
        /* Stage 1 - find policy */
-       if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) {
+       if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
                err = -ENOENT;
                goto out;
        }
  
        /* Stage 2 - find and update state(s) */
        for (i = 0, mp = m; i < num_migrate; i++, mp++) {
-               if ((x = xfrm_migrate_state_find(mp))) {
+               if ((x = xfrm_migrate_state_find(mp, net))) {
                        x_cur[nx_cur] = x;
                        nx_cur++;
                        if ((xc = xfrm_state_migrate(x, mp))) {
diff --combined net/xfrm/xfrm_state.c
index 8ed9d0dd45664ef2c414bbf2ea5f0f0a4bf71ef8,8d11d28991a4b7a0c760e403d578199fae8d9a33..a26b7aa794755f970756cadb3c817bfc500956d2
@@@ -35,8 -35,6 +35,6 @@@
        destination/tunnel endpoint. (output)
   */
  
- static DEFINE_SPINLOCK(xfrm_state_lock);
  static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
  
  static inline unsigned int xfrm_dst_hash(struct net *net,
@@@ -127,7 -125,7 +125,7 @@@ static void xfrm_hash_resize(struct wor
                goto out_unlock;
        }
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
  
        nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
        for (i = net->xfrm.state_hmask; i >= 0; i--)
        net->xfrm.state_byspi = nspi;
        net->xfrm.state_hmask = nhashmask;
  
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
        osize = (ohashmask + 1) * sizeof(struct hlist_head);
        xfrm_hash_free(odst, osize);
@@@ -374,8 -372,6 +372,6 @@@ static void xfrm_state_gc_task(struct w
  
        hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
                xfrm_state_gc_destroy(x);
-       wake_up(&net->xfrm.km_waitq);
  }
  
  static inline unsigned long make_jiffies(long secs)
                return secs*HZ;
  }
  
- static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
+ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
  {
        struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);
        struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer);
-       struct net *net = xs_net(x);
        unsigned long now = get_seconds();
        long next = LONG_MAX;
        int warn = 0;
        if (warn)
                km_state_expired(x, 0, 0);
  resched:
-       if (next != LONG_MAX){
+       if (next != LONG_MAX) {
                tasklet_hrtimer_start(&x->mtimer, ktime_set(next, 0), HRTIMER_MODE_REL);
        }
  
        goto out;
  
  expired:
-       if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) {
+       if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0)
                x->km.state = XFRM_STATE_EXPIRED;
-               wake_up(&net->xfrm.km_waitq);
-               next = 2;
-               goto resched;
-       }
  
        err = __xfrm_state_delete(x);
        if (!err)
@@@ -535,14 -526,14 +526,14 @@@ int __xfrm_state_delete(struct xfrm_sta
  
        if (x->km.state != XFRM_STATE_DEAD) {
                x->km.state = XFRM_STATE_DEAD;
-               spin_lock(&xfrm_state_lock);
+               spin_lock(&net->xfrm.xfrm_state_lock);
                list_del(&x->km.all);
                hlist_del(&x->bydst);
                hlist_del(&x->bysrc);
                if (x->id.spi)
                        hlist_del(&x->byspi);
                net->xfrm.state_num--;
-               spin_unlock(&xfrm_state_lock);
+               spin_unlock(&net->xfrm.xfrm_state_lock);
  
                /* All xfrm_state objects are created by xfrm_state_alloc.
                 * The xfrm_state_alloc call gives a reference, and that
@@@ -603,7 -594,7 +594,7 @@@ int xfrm_state_flush(struct net *net, u
  {
        int i, err = 0, cnt = 0;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        err = xfrm_state_flush_secctx_check(net, proto, audit_info);
        if (err)
                goto out;
@@@ -616,7 -607,7 +607,7 @@@ restart
                        if (!xfrm_state_kern(x) &&
                            xfrm_id_proto_match(x->id.proto, proto)) {
                                xfrm_state_hold(x);
-                               spin_unlock_bh(&xfrm_state_lock);
+                               spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
                                err = xfrm_state_delete(x);
                                xfrm_audit_state_delete(x, err ? 0 : 1,
                                if (!err)
                                        cnt++;
  
-                               spin_lock_bh(&xfrm_state_lock);
+                               spin_lock_bh(&net->xfrm.xfrm_state_lock);
                                goto restart;
                        }
                }
                err = 0;
  
  out:
-       spin_unlock_bh(&xfrm_state_lock);
-       wake_up(&net->xfrm.km_waitq);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        return err;
  }
  EXPORT_SYMBOL(xfrm_state_flush);
  
  void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
  {
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        si->sadcnt = net->xfrm.state_num;
        si->sadhcnt = net->xfrm.state_hmask;
        si->sadhmcnt = xfrm_state_hashmax;
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  }
  EXPORT_SYMBOL(xfrm_sad_getinfo);
  
@@@ -801,7 -791,7 +791,7 @@@ xfrm_state_find(const xfrm_address_t *d
  
        to_put = NULL;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
        hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
                if (x->props.family == encap_family &&
@@@ -886,7 -876,7 +876,7 @@@ out
                xfrm_state_hold(x);
        else
                *err = acquire_in_progress ? -EAGAIN : error;
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        if (to_put)
                xfrm_state_put(to_put);
        return x;
@@@ -900,7 -890,7 +890,7 @@@ xfrm_stateonly_find(struct net *net, u3
        unsigned int h;
        struct xfrm_state *rx = NULL, *x = NULL;
  
-       spin_lock(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
        hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
                if (x->props.family == family &&
  
        if (rx)
                xfrm_state_hold(rx);
-       spin_unlock(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
  
        return rx;
  }
  EXPORT_SYMBOL(xfrm_stateonly_find);
  
+ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
+                                             unsigned short family)
+ {
+       struct xfrm_state *x;
+       struct xfrm_state_walk *w;
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
+       list_for_each_entry(w, &net->xfrm.state_all, all) {
+               x = container_of(w, struct xfrm_state, km);
+               if (x->props.family != family ||
+                       x->id.spi != spi)
+                       continue;
+               spin_unlock_bh(&net->xfrm.xfrm_state_lock);
+               xfrm_state_hold(x);
+               return x;
+       }
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
+       return NULL;
+ }
+ EXPORT_SYMBOL(xfrm_state_lookup_byspi);
  static void __xfrm_state_insert(struct xfrm_state *x)
  {
        struct net *net = xs_net(x);
        if (x->replay_maxage)
                mod_timer(&x->rtimer, jiffies + x->replay_maxage);
  
-       wake_up(&net->xfrm.km_waitq);
        net->xfrm.state_num++;
  
        xfrm_hash_grow_check(net, x->bydst.next != NULL);
  }
  
- /* xfrm_state_lock is held */
+ /* net->xfrm.xfrm_state_lock is held */
  static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
  {
        struct net *net = xs_net(xnew);
  
  void xfrm_state_insert(struct xfrm_state *x)
  {
-       spin_lock_bh(&xfrm_state_lock);
+       struct net *net = xs_net(x);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        __xfrm_state_bump_genids(x);
        __xfrm_state_insert(x);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  }
  EXPORT_SYMBOL(xfrm_state_insert);
  
- /* xfrm_state_lock is held */
+ /* net->xfrm.xfrm_state_lock is held */
  static struct xfrm_state *__find_acq_core(struct net *net,
                                          const struct xfrm_mark *m,
                                          unsigned short family, u8 mode,
@@@ -1079,7 -1091,7 +1091,7 @@@ int xfrm_state_add(struct xfrm_state *x
  
        to_put = NULL;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
  
        x1 = __xfrm_state_locate(x, use_spi, family);
        if (x1) {
        err = 0;
  
  out:
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
        if (x1) {
                xfrm_state_delete(x1);
        return NULL;
  }
  
- /* xfrm_state_lock is held */
- struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
+ /* net->xfrm.xfrm_state_lock is held */
+ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
  {
        unsigned int h;
        struct xfrm_state *x;
  
        if (m->reqid) {
-               h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr,
+               h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
                                  m->reqid, m->old_family);
-               hlist_for_each_entry(x, init_net.xfrm.state_bydst+h, bydst) {
+               hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
                        if (x->props.mode != m->mode ||
                            x->id.proto != m->proto)
                                continue;
                        return x;
                }
        } else {
-               h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr,
+               h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
                                  m->old_family);
-               hlist_for_each_entry(x, init_net.xfrm.state_bysrc+h, bysrc) {
+               hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
                        if (x->props.mode != m->mode ||
                            x->id.proto != m->proto)
                                continue;
  }
  EXPORT_SYMBOL(xfrm_migrate_state_find);
  
- struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
-                                      struct xfrm_migrate *m)
+ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
+                                     struct xfrm_migrate *m)
  {
        struct xfrm_state *xc;
        int err;
@@@ -1283,10 -1295,11 +1295,11 @@@ int xfrm_state_update(struct xfrm_stat
        struct xfrm_state *x1, *to_put;
        int err;
        int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
+       struct net *net = xs_net(x);
  
        to_put = NULL;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        x1 = __xfrm_state_locate(x, use_spi, x->props.family);
  
        err = -ESRCH;
        err = 0;
  
  out:
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
        if (to_put)
                xfrm_state_put(to_put);
@@@ -1357,7 -1370,7 +1370,7 @@@ int xfrm_state_check_expire(struct xfrm
        if (x->curlft.bytes >= x->lft.hard_byte_limit ||
            x->curlft.packets >= x->lft.hard_packet_limit) {
                x->km.state = XFRM_STATE_EXPIRED;
-               tasklet_hrtimer_start(&x->mtimer, ktime_set(0,0), HRTIMER_MODE_REL);
+               tasklet_hrtimer_start(&x->mtimer, ktime_set(0, 0), HRTIMER_MODE_REL);
                return -EINVAL;
        }
  
@@@ -1377,9 -1390,9 +1390,9 @@@ xfrm_state_lookup(struct net *net, u32 
  {
        struct xfrm_state *x;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        return x;
  }
  EXPORT_SYMBOL(xfrm_state_lookup);
@@@ -1391,9 -1404,9 +1404,9 @@@ xfrm_state_lookup_byaddr(struct net *ne
  {
        struct xfrm_state *x;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        return x;
  }
  EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
@@@ -1405,9 -1418,9 +1418,9 @@@ xfrm_find_acq(struct net *net, const st
  {
        struct xfrm_state *x;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
        return x;
  }
@@@ -1416,17 -1429,17 +1429,17 @@@ EXPORT_SYMBOL(xfrm_find_acq)
  #ifdef CONFIG_XFRM_SUB_POLICY
  int
  xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
-              unsigned short family)
+              unsigned short family, struct net *net)
  {
        int err = 0;
        struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
        if (!afinfo)
                return -EAFNOSUPPORT;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
        if (afinfo->tmpl_sort)
                err = afinfo->tmpl_sort(dst, src, n);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        xfrm_state_put_afinfo(afinfo);
        return err;
  }
@@@ -1438,13 -1451,15 +1451,15 @@@ xfrm_state_sort(struct xfrm_state **dst
  {
        int err = 0;
        struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
+       struct net *net = xs_net(*dst);
        if (!afinfo)
                return -EAFNOSUPPORT;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        if (afinfo->state_sort)
                err = afinfo->state_sort(dst, src, n);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        xfrm_state_put_afinfo(afinfo);
        return err;
  }
@@@ -1476,9 -1491,9 +1491,9 @@@ struct xfrm_state *xfrm_find_acq_byseq(
  {
        struct xfrm_state *x;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        x = __xfrm_find_acq_byseq(net, mark, seq);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        return x;
  }
  EXPORT_SYMBOL(xfrm_find_acq_byseq);
@@@ -1496,6 -1511,30 +1511,30 @@@ u32 xfrm_get_acqseq(void
  }
  EXPORT_SYMBOL(xfrm_get_acqseq);
  
+ int verify_spi_info(u8 proto, u32 min, u32 max)
+ {
+       switch (proto) {
+       case IPPROTO_AH:
+       case IPPROTO_ESP:
+               break;
+       case IPPROTO_COMP:
+               /* IPCOMP spi is 16-bits. */
+               if (max >= 0x10000)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+       if (min > max)
+               return -EINVAL;
+       return 0;
+ }
+ EXPORT_SYMBOL(verify_spi_info);
  int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
  {
        struct net *net = xs_net(x);
                x->id.spi = minspi;
        } else {
                u32 spi = 0;
-               for (h=0; h<high-low+1; h++) {
-                       spi = low + net_random()%(high-low+1);
+               for (h = 0; h < high-low+1; h++) {
+                       spi = low + prandom_u32()%(high-low+1);
                        x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
                        if (x0 == NULL) {
                                x->id.spi = htonl(spi);
                }
        }
        if (x->id.spi) {
-               spin_lock_bh(&xfrm_state_lock);
+               spin_lock_bh(&net->xfrm.xfrm_state_lock);
                h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
                hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
-               spin_unlock_bh(&xfrm_state_lock);
+               spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  
                err = 0;
        }
@@@ -1562,7 -1601,7 +1601,7 @@@ int xfrm_state_walk(struct net *net, st
        if (walk->seq != 0 && list_empty(&walk->all))
                return 0;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        if (list_empty(&walk->all))
                x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
        else
        }
        list_del_init(&walk->all);
  out:
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
        return err;
  }
  EXPORT_SYMBOL(xfrm_state_walk);
@@@ -1600,20 -1639,20 +1639,20 @@@ void xfrm_state_walk_init(struct xfrm_s
  }
  EXPORT_SYMBOL(xfrm_state_walk_init);
  
- void xfrm_state_walk_done(struct xfrm_state_walk *walk)
+ void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
  {
        if (list_empty(&walk->all))
                return;
  
-       spin_lock_bh(&xfrm_state_lock);
+       spin_lock_bh(&net->xfrm.xfrm_state_lock);
        list_del(&walk->all);
-       spin_unlock_bh(&xfrm_state_lock);
+       spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  }
  EXPORT_SYMBOL(xfrm_state_walk_done);
  
  static void xfrm_replay_timer_handler(unsigned long data)
  {
-       struct xfrm_state *x = (struct xfrm_state*)data;
+       struct xfrm_state *x = (struct xfrm_state *)data;
  
        spin_lock(&x->lock);
  
@@@ -1655,16 -1694,12 +1694,12 @@@ EXPORT_SYMBOL(km_state_notify)
  
  void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
  {
-       struct net *net = xs_net(x);
        struct km_event c;
  
        c.data.hard = hard;
        c.portid = portid;
        c.event = XFRM_MSG_EXPIRE;
        km_state_notify(x, &c);
-       if (hard)
-               wake_up(&net->xfrm.km_waitq);
  }
  
  EXPORT_SYMBOL(km_state_expired);
@@@ -1707,16 -1742,12 +1742,12 @@@ EXPORT_SYMBOL(km_new_mapping)
  
  void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
  {
-       struct net *net = xp_net(pol);
        struct km_event c;
  
        c.data.hard = hard;
        c.portid = portid;
        c.event = XFRM_MSG_POLEXPIRE;
        km_policy_notify(pol, dir, &c);
-       if (hard)
-               wake_up(&net->xfrm.km_waitq);
  }
  EXPORT_SYMBOL(km_policy_expired);
  
@@@ -2025,7 -2056,7 +2056,7 @@@ int __net_init xfrm_state_init(struct n
        INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
        INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
        INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
-       init_waitqueue_head(&net->xfrm.km_waitq);
+       spin_lock_init(&net->xfrm.xfrm_state_lock);
        return 0;
  
  out_byspi:
@@@ -2043,7 -2074,7 +2074,7 @@@ void xfrm_state_fini(struct net *net
  
        flush_work(&net->xfrm.state_hash_work);
        audit_info.loginuid = INVALID_UID;
 -      audit_info.sessionid = -1;
 +      audit_info.sessionid = (unsigned int)-1;
        audit_info.secid = 0;
        xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info);
        flush_work(&net->xfrm.state_gc_work);
@@@ -2070,7 -2101,7 +2101,7 @@@ static void xfrm_audit_helper_sainfo(st
                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
                                 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
  
-       switch(x->props.family) {
+       switch (x->props.family) {
        case AF_INET:
                audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
                                 &x->props.saddr.a4, &x->id.daddr.a4);
@@@ -2100,7 -2131,7 +2131,7 @@@ static void xfrm_audit_helper_pktinfo(s
                iph6 = ipv6_hdr(skb);
                audit_log_format(audit_buf,
                                 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x",
-                                &iph6->saddr,&iph6->daddr,
+                                &iph6->saddr, &iph6->daddr,
                                 iph6->flow_lbl[0] & 0x0f,
                                 iph6->flow_lbl[1],
                                 iph6->flow_lbl[2]);
  }
  
  void xfrm_audit_state_add(struct xfrm_state *x, int result,
 -                        kuid_t auid, u32 sessionid, u32 secid)
 +                        kuid_t auid, unsigned int sessionid, u32 secid)
  {
        struct audit_buffer *audit_buf;
  
  EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
  
  void xfrm_audit_state_delete(struct xfrm_state *x, int result,
 -                           kuid_t auid, u32 sessionid, u32 secid)
 +                           kuid_t auid, unsigned int sessionid, u32 secid)
  {
        struct audit_buffer *audit_buf;
  
diff --combined net/xfrm/xfrm_user.c
index ec97e13743e6ec32ff7e2a9a77a7056ebb8874b8,334856689b0d9861441a12b344b6fdcba5ce1dee..1ae3ec7c18b0de977b1b781c8fee72d8357543bc
@@@ -181,7 -181,9 +181,9 @@@ static int verify_newsa_info(struct xfr
                    attrs[XFRMA_ALG_AEAD]       ||
                    attrs[XFRMA_ALG_CRYPT]      ||
                    attrs[XFRMA_ALG_COMP]       ||
-                   attrs[XFRMA_TFCPAD])
+                   attrs[XFRMA_TFCPAD]         ||
+                   (ntohl(p->id.spi) >= 0x10000))
                        goto out;
                break;
  
@@@ -600,7 -602,7 +602,7 @@@ static int xfrm_add_sa(struct sk_buff *
        int err;
        struct km_event c;
        kuid_t loginuid = audit_get_loginuid(current);
 -      u32 sessionid = audit_get_sessionid(current);
 +      unsigned int sessionid = audit_get_sessionid(current);
        u32 sid;
  
        err = verify_newsa_info(p, attrs);
@@@ -679,7 -681,7 +681,7 @@@ static int xfrm_del_sa(struct sk_buff *
        struct km_event c;
        struct xfrm_usersa_id *p = nlmsg_data(nlh);
        kuid_t loginuid = audit_get_loginuid(current);
 -      u32 sessionid = audit_get_sessionid(current);
 +      unsigned int sessionid = audit_get_sessionid(current);
        u32 sid;
  
        x = xfrm_user_state_lookup(net, p, attrs, &err);
@@@ -877,7 -879,10 +879,10 @@@ static int dump_one_state(struct xfrm_s
  static int xfrm_dump_sa_done(struct netlink_callback *cb)
  {
        struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
-       xfrm_state_walk_done(walk);
+       struct sock *sk = cb->skb->sk;
+       struct net *net = sock_net(sk);
+       xfrm_state_walk_done(walk, net);
        return 0;
  }
  
@@@ -1074,29 -1079,6 +1079,6 @@@ out_noput
        return err;
  }
  
- static int verify_userspi_info(struct xfrm_userspi_info *p)
- {
-       switch (p->info.id.proto) {
-       case IPPROTO_AH:
-       case IPPROTO_ESP:
-               break;
-       case IPPROTO_COMP:
-               /* IPCOMP spi is 16-bits. */
-               if (p->max >= 0x10000)
-                       return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
-       }
-       if (p->min > p->max)
-               return -EINVAL;
-       return 0;
- }
  static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
                struct nlattr **attrs)
  {
        struct xfrm_mark m;
  
        p = nlmsg_data(nlh);
-       err = verify_userspi_info(p);
+       err = verify_spi_info(p->info.id.proto, p->min, p->max);
        if (err)
                goto out_noput;
  
@@@ -1189,6 -1171,8 +1171,8 @@@ static int verify_policy_type(u8 type
  
  static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
  {
+       int ret;
        switch (p->share) {
        case XFRM_SHARE_ANY:
        case XFRM_SHARE_SESSION:
                return -EINVAL;
        }
  
-       return verify_policy_dir(p->dir);
+       ret = verify_policy_dir(p->dir);
+       if (ret)
+               return ret;
+       if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir))
+               return -EINVAL;
+       return 0;
  }
  
  static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs)
@@@ -1405,7 -1395,7 +1395,7 @@@ static int xfrm_add_policy(struct sk_bu
        int err;
        int excl;
        kuid_t loginuid = audit_get_loginuid(current);
 -      u32 sessionid = audit_get_sessionid(current);
 +      unsigned int sessionid = audit_get_sessionid(current);
        u32 sid;
  
        err = verify_newpolicy_info(p);
@@@ -1547,8 -1537,9 +1537,9 @@@ static int dump_one_policy(struct xfrm_
  static int xfrm_dump_policy_done(struct netlink_callback *cb)
  {
        struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
+       struct net *net = sock_net(cb->skb->sk);
  
-       xfrm_policy_walk_done(walk);
+       xfrm_policy_walk_done(walk, net);
        return 0;
  }
  
@@@ -1663,7 -1654,7 +1654,7 @@@ static int xfrm_get_policy(struct sk_bu
                }
        } else {
                kuid_t loginuid = audit_get_loginuid(current);
 -              u32 sessionid = audit_get_sessionid(current);
 +              unsigned int sessionid = audit_get_sessionid(current);
                u32 sid;
  
                security_task_getsecid(current, &sid);
@@@ -1740,11 -1731,11 +1731,11 @@@ static int build_aevent(struct sk_buff 
                return -EMSGSIZE;
  
        id = nlmsg_data(nlh);
-       memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr));
+       memcpy(&id->sa_id.daddr, &x->id.daddr, sizeof(x->id.daddr));
        id->sa_id.spi = x->id.spi;
        id->sa_id.family = x->props.family;
        id->sa_id.proto = x->id.proto;
-       memcpy(&id->saddr, &x->props.saddr,sizeof(x->props.saddr));
+       memcpy(&id->saddr, &x->props.saddr, sizeof(x->props.saddr));
        id->reqid = x->props.reqid;
        id->flags = c->data.aevent;
  
@@@ -1833,7 -1824,7 +1824,7 @@@ static int xfrm_new_ae(struct sk_buff *
        struct net *net = sock_net(skb->sk);
        struct xfrm_state *x;
        struct km_event c;
-       int err = - EINVAL;
+       int err = -EINVAL;
        u32 mark = 0;
        struct xfrm_mark m;
        struct xfrm_aevent_id *p = nlmsg_data(nlh);
@@@ -1959,7 -1950,7 +1950,7 @@@ static int xfrm_add_pol_expire(struct s
        err = 0;
        if (up->hard) {
                kuid_t loginuid = audit_get_loginuid(current);
 -              u32 sessionid = audit_get_sessionid(current);
 +              unsigned int sessionid = audit_get_sessionid(current);
                u32 sid;
  
                security_task_getsecid(current, &sid);
@@@ -2002,7 -1993,7 +1993,7 @@@ static int xfrm_add_sa_expire(struct sk
  
        if (ue->hard) {
                kuid_t loginuid = audit_get_loginuid(current);
 -              u32 sessionid = audit_get_sessionid(current);
 +              unsigned int sessionid = audit_get_sessionid(current);
                u32 sid;
  
                security_task_getsecid(current, &sid);
@@@ -2129,6 -2120,7 +2120,7 @@@ static int xfrm_do_migrate(struct sk_bu
        u8 type;
        int err;
        int n = 0;
+       struct net *net = sock_net(skb->sk);
  
        if (attrs[XFRMA_MIGRATE] == NULL)
                return -EINVAL;
        if (!n)
                return 0;
  
-       xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp);
+       xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net);
  
        return 0;
  }
@@@ -2394,9 -2386,11 +2386,11 @@@ static int xfrm_user_rcv_msg(struct sk_
  
  static void xfrm_netlink_rcv(struct sk_buff *skb)
  {
-       mutex_lock(&xfrm_cfg_mutex);
+       struct net *net = sock_net(skb->sk);
+       mutex_lock(&net->xfrm.xfrm_cfg_mutex);
        netlink_rcv_skb(skb, &xfrm_user_rcv_msg);
-       mutex_unlock(&xfrm_cfg_mutex);
+       mutex_unlock(&net->xfrm.xfrm_cfg_mutex);
  }
  
  static inline size_t xfrm_expire_msgsize(void)