[linux-next] LinuxNextTracking branch, master, updated. next-20180326

batman at open-mesh.org batman at open-mesh.org
Tue Mar 27 00:16:08 CEST 2018


The following commit has been merged in the master branch:
commit 03fe2debbb2771fb90881e4ce8109b09cf772a5c
Merge: 6686c459e1449a3ee5f3fd313b0a559ace7a700e f36b7534b83357cf52e747905de6d65b4f7c2512
Author: David S. Miller <davem at davemloft.net>
Date:   Fri Mar 23 11:24:57 2018 -0400

    Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
    
    Fun set of conflict resolutions here...
    
    For the mac80211 stuff, these were fortunately just parallel
    adds.  Trivially resolved.
    
    In drivers/net/phy/phy.c we had a bug fix in 'net' that moved the
    function phy_disable_interrupts() earlier in the file, whilst in
    'net-next' the phy_error() call from this function was removed.
    
    In net/ipv4/xfrm4_policy.c, David Ahern's changes to remove the
    'rt_table_id' member of rtable collided with a bug fix in 'net' that
    added a new struct member "rt_mtu_locked" which needs to be copied
    over here.
    
    The mlxsw driver conflict consisted of net-next separating
    the span code and definitions into separate files, whilst
    a 'net' bug fix made some changes to that moved code.
    
    The mlx5 infiniband conflict resolution was quite non-trivial,
    the RDMA tree's merge commit was used as a guide here, and
    here are their notes:
    
    ====================
    
        Due to bug fixes found by the syzkaller bot and taken into the for-rc
        branch after development for the 4.17 merge window had already started
        being taken into the for-next branch, there were fairly non-trivial
        merge issues that would need to be resolved between the for-rc branch
        and the for-next branch.  This merge resolves those conflicts and
        provides a unified base upon which ongoing development for 4.17 can
        be based.
    
        Conflicts:
                drivers/infiniband/hw/mlx5/main.c - Commit 42cea83f9524
                (IB/mlx5: Fix cleanup order on unload) added to for-rc and
                commit b5ca15ad7e61 (IB/mlx5: Add proper representors support)
                add as part of the devel cycle both needed to modify the
                init/de-init functions used by mlx5.  To support the new
                representors, the new functions added by the cleanup patch
                needed to be made non-static, and the init/de-init list
                added by the representors patch needed to be modified to
                match the init/de-init list changes made by the cleanup
                patch.
        Updates:
                drivers/infiniband/hw/mlx5/mlx5_ib.h - Update function
                prototypes added by representors patch to reflect new function
                names as changed by cleanup patch
                drivers/infiniband/hw/mlx5/ib_rep.c - Update init/de-init
                stage list to match new order from cleanup patch
    ====================
    
    Signed-off-by: David S. Miller <davem at davemloft.net>

diff --combined Documentation/devicetree/bindings/net/dsa/marvell.txt
index caf71e2fe24a,8c033d48e2ba..60d50a2b0323
--- a/Documentation/devicetree/bindings/net/dsa/marvell.txt
+++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt
@@@ -13,18 -13,9 +13,18 @@@ placed as a child node of an mdio devic
  The properties described here are those specific to Marvell devices.
  Additional required and optional properties can be found in dsa.txt.
  
 +The compatibility string is used only to find an identification register,
 +which is at a different MDIO base address in different switch families.
 +- "marvell,mv88e6085"	: Switch has base address 0x10. Use with models:
 +			  6085, 6095, 6097, 6123, 6131, 6141, 6161, 6165,
 +			  6171, 6172, 6175, 6176, 6185, 6240, 6320, 6321,
 +			  6341, 6350, 6351, 6352
 +- "marvell,mv88e6190"	: Switch has base address 0x00. Use with models:
 +			  6190, 6190X, 6191, 6290, 6390, 6390X
 +
  Required properties:
  - compatible		: Should be one of "marvell,mv88e6085" or
 -			  "marvell,mv88e6190"
 +			  "marvell,mv88e6190" as indicated above
  - reg			: Address on the MII bus for the switch.
  
  Optional properties:
@@@ -59,14 -50,15 +59,15 @@@ Example
  			compatible = "marvell,mv88e6085";
  			reg = <0>;
  			reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
- 		};
- 		mdio {
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 			switch1phy0: switch1phy0 at 0 {
- 				reg = <0>;
- 				interrupt-parent = <&switch0>;
- 				interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ 
+ 			mdio {
+ 				#address-cells = <1>;
+ 				#size-cells = <0>;
+ 				switch1phy0: switch1phy0 at 0 {
+ 					reg = <0>;
+ 					interrupt-parent = <&switch0>;
+ 					interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ 				};
  			};
  		};
  	};
@@@ -83,23 -75,24 +84,24 @@@
  			compatible = "marvell,mv88e6390";
  			reg = <0>;
  			reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
- 		};
- 		mdio {
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 			switch1phy0: switch1phy0 at 0 {
- 				reg = <0>;
- 				interrupt-parent = <&switch0>;
- 				interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ 
+ 			mdio {
+ 				#address-cells = <1>;
+ 				#size-cells = <0>;
+ 				switch1phy0: switch1phy0 at 0 {
+ 					reg = <0>;
+ 					interrupt-parent = <&switch0>;
+ 					interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ 				};
  			};
- 		};
  
- 		mdio1 {
- 			compatible = "marvell,mv88e6xxx-mdio-external";
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 			switch1phy9: switch1phy0 at 9 {
- 				reg = <9>;
+ 			mdio1 {
+ 				compatible = "marvell,mv88e6xxx-mdio-external";
+ 				#address-cells = <1>;
+ 				#size-cells = <0>;
+ 				switch1phy9: switch1phy0 at 9 {
+ 					reg = <9>;
+ 				};
  			};
  		};
  	};
diff --combined MAINTAINERS
index 214c9bca232a,73c0cdabf755..b3ea844cf228
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@@ -8596,15 -8596,6 +8596,15 @@@ S:	Maintaine
  F:	Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
  F:	drivers/iio/potentiometer/mcp4531.c
  
 +MCR20A IEEE-802.15.4 RADIO DRIVER
 +M:	Xue Liu <liuxuenetmail at gmail.com>
 +L:	linux-wpan at vger.kernel.org
 +W:	https://github.com/xueliu/mcr20a-linux
 +S:	Maintained
 +F:	drivers/net/ieee802154/mcr20a.c
 +F:	drivers/net/ieee802154/mcr20a.h
 +F:	Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt
 +
  MEASUREMENT COMPUTING CIO-DAC IIO DRIVER
  M:	William Breathitt Gray <vilhelm.gray at gmail.com>
  L:	linux-iio at vger.kernel.org
@@@ -9161,13 -9152,6 +9161,13 @@@ F:	drivers/net/dsa/microchip/
  F:	include/linux/platform_data/microchip-ksz.h
  F:	Documentation/devicetree/bindings/net/dsa/ksz.txt
  
 +MICROCHIP LAN743X ETHERNET DRIVER
 +M:	Bryan Whitehead <bryan.whitehead at microchip.com>
 +M:	Microchip Linux Driver Support <UNGLinuxDriver at microchip.com>
 +L:	netdev at vger.kernel.org
 +S:	Maintained
 +F:	drivers/net/ethernet/microchip/lan743x_*
 +
  MICROCHIP USB251XB DRIVER
  M:	Richard Leitner <richard.leitner at skidata.com>
  L:	linux-usb at vger.kernel.org
@@@ -9941,6 -9925,13 +9941,13 @@@ F:	Documentation/ABI/stable/sysfs-bus-n
  F:	include/linux/nvmem-consumer.h
  F:	include/linux/nvmem-provider.h
  
+ NXP SGTL5000 DRIVER
+ M:	Fabio Estevam <fabio.estevam at nxp.com>
+ L:	alsa-devel at alsa-project.org (moderated for non-subscribers)
+ S:	Maintained
+ F:	Documentation/devicetree/bindings/sound/sgtl5000.txt
+ F:	sound/soc/codecs/sgtl5000*
+ 
  NXP TDA998X DRM DRIVER
  M:	Russell King <linux at armlinux.org.uk>
  S:	Supported
@@@ -10343,7 -10334,7 +10350,7 @@@ F:	drivers/oprofile
  F:	include/linux/oprofile.h
  
  ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
- M:	Mark Fasheh <mfasheh at versity.com>
+ M:	Mark Fasheh <mark at fasheh.com>
  M:	Joel Becker <jlbec at evilplan.org>
  L:	ocfs2-devel at oss.oracle.com (moderated for non-subscribers)
  W:	http://ocfs2.wiki.kernel.org
@@@ -10853,6 -10844,7 +10860,7 @@@ F:	drivers/platform/x86/peaq-wmi.
  PER-CPU MEMORY ALLOCATOR
  M:	Tejun Heo <tj at kernel.org>
  M:	Christoph Lameter <cl at linux.com>
+ M:	Dennis Zhou <dennisszhou at gmail.com>
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git
  S:	Maintained
  F:	include/linux/percpu*.h
@@@ -12123,6 -12115,7 +12131,7 @@@ M:	Sylwester Nawrocki <s.nawrocki at samsu
  L:	alsa-devel at alsa-project.org (moderated for non-subscribers)
  S:	Supported
  F:	sound/soc/samsung/
+ F:	Documentation/devicetree/bindings/sound/samsung*
  
  SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
  M:	Krzysztof Kozlowski <krzk at kernel.org>
diff --combined arch/x86/net/bpf_jit_comp.c
index eb661fff94d7,ce5b2ebd5701..b725154182cc
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@@ -11,10 -11,10 +11,10 @@@
  #include <linux/netdevice.h>
  #include <linux/filter.h>
  #include <linux/if_vlan.h>
 -#include <asm/cacheflush.h>
 +#include <linux/bpf.h>
 +
  #include <asm/set_memory.h>
  #include <asm/nospec-branch.h>
 -#include <linux/bpf.h>
  
  /*
   * assembly code in arch/x86/net/bpf_jit.S
@@@ -61,12 -61,7 +61,12 @@@ static bool is_imm8(int value
  
  static bool is_simm32(s64 value)
  {
 -	return value == (s64) (s32) value;
 +	return value == (s64)(s32)value;
 +}
 +
 +static bool is_uimm32(u64 value)
 +{
 +	return value == (u64)(u32)value;
  }
  
  /* mov dst, src */
@@@ -103,6 -98,16 +103,6 @@@ static int bpf_size_to_x86_bytes(int bp
  #define X86_JLE 0x7E
  #define X86_JG  0x7F
  
 -static void bpf_flush_icache(void *start, void *end)
 -{
 -	mm_segment_t old_fs = get_fs();
 -
 -	set_fs(KERNEL_DS);
 -	smp_wmb();
 -	flush_icache_range((unsigned long)start, (unsigned long)end);
 -	set_fs(old_fs);
 -}
 -
  #define CHOOSE_LOAD_FUNC(K, func) \
  	((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
  
@@@ -207,7 -212,7 +207,7 @@@ struct jit_context 
  /* emit x64 prologue code for BPF program and check it's size.
   * bpf_tail_call helper will skip it while jumping into another program
   */
 -static void emit_prologue(u8 **pprog, u32 stack_depth)
 +static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf)
  {
  	u8 *prog = *pprog;
  	int cnt = 0;
@@@ -242,21 -247,18 +242,21 @@@
  	/* mov qword ptr [rbp+24],r15 */
  	EMIT4(0x4C, 0x89, 0x7D, 24);
  
 -	/* Clear the tail call counter (tail_call_cnt): for eBPF tail calls
 -	 * we need to reset the counter to 0. It's done in two instructions,
 -	 * resetting rax register to 0 (xor on eax gets 0 extended), and
 -	 * moving it to the counter location.
 -	 */
 +	if (!ebpf_from_cbpf) {
 +		/* Clear the tail call counter (tail_call_cnt): for eBPF tail
 +		 * calls we need to reset the counter to 0. It's done in two
 +		 * instructions, resetting rax register to 0, and moving it
 +		 * to the counter location.
 +		 */
  
 -	/* xor eax, eax */
 -	EMIT2(0x31, 0xc0);
 -	/* mov qword ptr [rbp+32], rax */
 -	EMIT4(0x48, 0x89, 0x45, 32);
 +		/* xor eax, eax */
 +		EMIT2(0x31, 0xc0);
 +		/* mov qword ptr [rbp+32], rax */
 +		EMIT4(0x48, 0x89, 0x45, 32);
 +
 +		BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
 +	}
  
 -	BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
  	*pprog = prog;
  }
  
@@@ -354,86 -356,6 +354,86 @@@ static void emit_load_skb_data_hlen(u8 
  	*pprog = prog;
  }
  
 +static void emit_mov_imm32(u8 **pprog, bool sign_propagate,
 +			   u32 dst_reg, const u32 imm32)
 +{
 +	u8 *prog = *pprog;
 +	u8 b1, b2, b3;
 +	int cnt = 0;
 +
 +	/* optimization: if imm32 is positive, use 'mov %eax, imm32'
 +	 * (which zero-extends imm32) to save 2 bytes.
 +	 */
 +	if (sign_propagate && (s32)imm32 < 0) {
 +		/* 'mov %rax, imm32' sign extends imm32 */
 +		b1 = add_1mod(0x48, dst_reg);
 +		b2 = 0xC7;
 +		b3 = 0xC0;
 +		EMIT3_off32(b1, b2, add_1reg(b3, dst_reg), imm32);
 +		goto done;
 +	}
 +
 +	/* optimization: if imm32 is zero, use 'xor %eax, %eax'
 +	 * to save 3 bytes.
 +	 */
 +	if (imm32 == 0) {
 +		if (is_ereg(dst_reg))
 +			EMIT1(add_2mod(0x40, dst_reg, dst_reg));
 +		b2 = 0x31; /* xor */
 +		b3 = 0xC0;
 +		EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
 +		goto done;
 +	}
 +
 +	/* mov %eax, imm32 */
 +	if (is_ereg(dst_reg))
 +		EMIT1(add_1mod(0x40, dst_reg));
 +	EMIT1_off32(add_1reg(0xB8, dst_reg), imm32);
 +done:
 +	*pprog = prog;
 +}
 +
 +static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
 +			   const u32 imm32_hi, const u32 imm32_lo)
 +{
 +	u8 *prog = *pprog;
 +	int cnt = 0;
 +
 +	if (is_uimm32(((u64)imm32_hi << 32) | (u32)imm32_lo)) {
 +		/* For emitting plain u32, where sign bit must not be
 +		 * propagated LLVM tends to load imm64 over mov32
 +		 * directly, so save couple of bytes by just doing
 +		 * 'mov %eax, imm32' instead.
 +		 */
 +		emit_mov_imm32(&prog, false, dst_reg, imm32_lo);
 +	} else {
 +		/* movabsq %rax, imm64 */
 +		EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
 +		EMIT(imm32_lo, 4);
 +		EMIT(imm32_hi, 4);
 +	}
 +
 +	*pprog = prog;
 +}
 +
 +static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
 +{
 +	u8 *prog = *pprog;
 +	int cnt = 0;
 +
 +	if (is64) {
 +		/* mov dst, src */
 +		EMIT_mov(dst_reg, src_reg);
 +	} else {
 +		/* mov32 dst, src */
 +		if (is_ereg(dst_reg) || is_ereg(src_reg))
 +			EMIT1(add_2mod(0x40, dst_reg, src_reg));
 +		EMIT2(0x89, add_2reg(0xC0, dst_reg, src_reg));
 +	}
 +
 +	*pprog = prog;
 +}
 +
  static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
  		  int oldproglen, struct jit_context *ctx)
  {
@@@ -447,8 -369,7 +447,8 @@@
  	int proglen = 0;
  	u8 *prog = temp;
  
 -	emit_prologue(&prog, bpf_prog->aux->stack_depth);
 +	emit_prologue(&prog, bpf_prog->aux->stack_depth,
 +		      bpf_prog_was_classic(bpf_prog));
  
  	if (seen_ld_abs)
  		emit_load_skb_data_hlen(&prog);
@@@ -457,7 -378,7 +457,7 @@@
  		const s32 imm32 = insn->imm;
  		u32 dst_reg = insn->dst_reg;
  		u32 src_reg = insn->src_reg;
 -		u8 b1 = 0, b2 = 0, b3 = 0;
 +		u8 b2 = 0, b3 = 0;
  		s64 jmp_offset;
  		u8 jmp_cond;
  		bool reload_skb_data;
@@@ -493,11 -414,16 +493,11 @@@
  			EMIT2(b2, add_2reg(0xC0, dst_reg, src_reg));
  			break;
  
 -			/* mov dst, src */
  		case BPF_ALU64 | BPF_MOV | BPF_X:
 -			EMIT_mov(dst_reg, src_reg);
 -			break;
 -
 -			/* mov32 dst, src */
  		case BPF_ALU | BPF_MOV | BPF_X:
 -			if (is_ereg(dst_reg) || is_ereg(src_reg))
 -				EMIT1(add_2mod(0x40, dst_reg, src_reg));
 -			EMIT2(0x89, add_2reg(0xC0, dst_reg, src_reg));
 +			emit_mov_reg(&prog,
 +				     BPF_CLASS(insn->code) == BPF_ALU64,
 +				     dst_reg, src_reg);
  			break;
  
  			/* neg dst */
@@@ -560,13 -486,58 +560,13 @@@
  			break;
  
  		case BPF_ALU64 | BPF_MOV | BPF_K:
 -			/* optimization: if imm32 is positive,
 -			 * use 'mov eax, imm32' (which zero-extends imm32)
 -			 * to save 2 bytes
 -			 */
 -			if (imm32 < 0) {
 -				/* 'mov rax, imm32' sign extends imm32 */
 -				b1 = add_1mod(0x48, dst_reg);
 -				b2 = 0xC7;
 -				b3 = 0xC0;
 -				EMIT3_off32(b1, b2, add_1reg(b3, dst_reg), imm32);
 -				break;
 -			}
 -
  		case BPF_ALU | BPF_MOV | BPF_K:
 -			/* optimization: if imm32 is zero, use 'xor <dst>,<dst>'
 -			 * to save 3 bytes.
 -			 */
 -			if (imm32 == 0) {
 -				if (is_ereg(dst_reg))
 -					EMIT1(add_2mod(0x40, dst_reg, dst_reg));
 -				b2 = 0x31; /* xor */
 -				b3 = 0xC0;
 -				EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
 -				break;
 -			}
 -
 -			/* mov %eax, imm32 */
 -			if (is_ereg(dst_reg))
 -				EMIT1(add_1mod(0x40, dst_reg));
 -			EMIT1_off32(add_1reg(0xB8, dst_reg), imm32);
 +			emit_mov_imm32(&prog, BPF_CLASS(insn->code) == BPF_ALU64,
 +				       dst_reg, imm32);
  			break;
  
  		case BPF_LD | BPF_IMM | BPF_DW:
 -			/* optimization: if imm64 is zero, use 'xor <dst>,<dst>'
 -			 * to save 7 bytes.
 -			 */
 -			if (insn[0].imm == 0 && insn[1].imm == 0) {
 -				b1 = add_2mod(0x48, dst_reg, dst_reg);
 -				b2 = 0x31; /* xor */
 -				b3 = 0xC0;
 -				EMIT3(b1, b2, add_2reg(b3, dst_reg, dst_reg));
 -
 -				insn++;
 -				i++;
 -				break;
 -			}
 -
 -			/* movabsq %rax, imm64 */
 -			EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
 -			EMIT(insn[0].imm, 4);
 -			EMIT(insn[1].imm, 4);
 -
 +			emit_mov_imm64(&prog, dst_reg, insn[1].imm, insn[0].imm);
  			insn++;
  			i++;
  			break;
@@@ -623,38 -594,36 +623,38 @@@
  		case BPF_ALU | BPF_MUL | BPF_X:
  		case BPF_ALU64 | BPF_MUL | BPF_K:
  		case BPF_ALU64 | BPF_MUL | BPF_X:
 -			EMIT1(0x50); /* push rax */
 -			EMIT1(0x52); /* push rdx */
 +		{
 +			bool is64 = BPF_CLASS(insn->code) == BPF_ALU64;
 +
 +			if (dst_reg != BPF_REG_0)
 +				EMIT1(0x50); /* push rax */
 +			if (dst_reg != BPF_REG_3)
 +				EMIT1(0x52); /* push rdx */
  
  			/* mov r11, dst_reg */
  			EMIT_mov(AUX_REG, dst_reg);
  
  			if (BPF_SRC(insn->code) == BPF_X)
 -				/* mov rax, src_reg */
 -				EMIT_mov(BPF_REG_0, src_reg);
 +				emit_mov_reg(&prog, is64, BPF_REG_0, src_reg);
  			else
 -				/* mov rax, imm32 */
 -				EMIT3_off32(0x48, 0xC7, 0xC0, imm32);
 +				emit_mov_imm32(&prog, is64, BPF_REG_0, imm32);
  
 -			if (BPF_CLASS(insn->code) == BPF_ALU64)
 +			if (is64)
  				EMIT1(add_1mod(0x48, AUX_REG));
  			else if (is_ereg(AUX_REG))
  				EMIT1(add_1mod(0x40, AUX_REG));
  			/* mul(q) r11 */
  			EMIT2(0xF7, add_1reg(0xE0, AUX_REG));
  
 -			/* mov r11, rax */
 -			EMIT_mov(AUX_REG, BPF_REG_0);
 -
 -			EMIT1(0x5A); /* pop rdx */
 -			EMIT1(0x58); /* pop rax */
 -
 -			/* mov dst_reg, r11 */
 -			EMIT_mov(dst_reg, AUX_REG);
 +			if (dst_reg != BPF_REG_3)
 +				EMIT1(0x5A); /* pop rdx */
 +			if (dst_reg != BPF_REG_0) {
 +				/* mov dst_reg, rax */
 +				EMIT_mov(dst_reg, BPF_REG_0);
 +				EMIT1(0x58); /* pop rax */
 +			}
  			break;
 -
 +		}
  			/* shifts */
  		case BPF_ALU | BPF_LSH | BPF_K:
  		case BPF_ALU | BPF_RSH | BPF_K:
@@@ -672,11 -641,7 +672,11 @@@
  			case BPF_RSH: b3 = 0xE8; break;
  			case BPF_ARSH: b3 = 0xF8; break;
  			}
 -			EMIT3(0xC1, add_1reg(b3, dst_reg), imm32);
 +
 +			if (imm32 == 1)
 +				EMIT2(0xD1, add_1reg(b3, dst_reg));
 +			else
 +				EMIT3(0xC1, add_1reg(b3, dst_reg), imm32);
  			break;
  
  		case BPF_ALU | BPF_LSH | BPF_X:
@@@ -1223,7 -1188,7 +1223,7 @@@ skip_init_addrs
  	 * may converge on the last pass. In such case do one more
  	 * pass to emit the final image
  	 */
- 	for (pass = 0; pass < 10 || image; pass++) {
+ 	for (pass = 0; pass < 20 || image; pass++) {
  		proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
  		if (proglen <= 0) {
  			image = NULL;
@@@ -1250,12 -1215,14 +1250,13 @@@
  			}
  		}
  		oldproglen = proglen;
+ 		cond_resched();
  	}
  
  	if (bpf_jit_enable > 1)
  		bpf_jit_dump(prog->len, proglen, pass + 1, image);
  
  	if (image) {
 -		bpf_flush_icache(header, image + proglen);
  		if (!prog->is_func || extra_pass) {
  			bpf_jit_binary_lock_ro(header);
  		} else {
diff --combined drivers/bluetooth/btusb.c
index fa4ce83893bb,366a49c7c08f..5cd868ea28ed
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@@ -231,7 -231,6 +231,6 @@@ static const struct usb_device_id black
  	{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
- 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@@ -264,6 -263,7 +263,7 @@@
  	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
  
  	/* QCA ROME chipset */
+ 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME },
  	{ USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
  	{ USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME },
  	{ USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME },
@@@ -340,7 -340,6 +340,7 @@@
  
  	/* Intel Bluetooth devices */
  	{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW },
 +	{ USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW },
  	{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
  	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
  	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
@@@ -375,9 -374,6 +375,9 @@@
  	{ USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK },
  	{ USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
  
 +	/* Additional Realtek 8822BE Bluetooth devices */
 +	{ USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK },
 +
  	/* Silicon Wave based devices */
  	{ USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
  
@@@ -390,10 -386,10 +390,10 @@@
   */
  static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
  	{
- 		/* Lenovo Yoga 920 (QCA Rome device 0cf3:e300) */
+ 		/* Dell OptiPlex 3060 (QCA ROME device 0cf3:e007) */
  		.matches = {
- 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- 			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920"),
+ 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 3060"),
  		},
  	},
  	{}
@@@ -2077,8 -2073,6 +2077,8 @@@ static int btusb_setup_intel_new(struc
  	case 0x0c:	/* WsP */
  	case 0x11:	/* JfP */
  	case 0x12:	/* ThP */
 +	case 0x13:	/* HrP */
 +	case 0x14:	/* QnJ, IcP */
  		break;
  	default:
  		BT_ERR("%s: Unsupported Intel hardware variant (%u)",
@@@ -2171,8 -2165,6 +2171,8 @@@
  		break;
  	case 0x11:	/* JfP */
  	case 0x12:	/* ThP */
 +	case 0x13:	/* HrP */
 +	case 0x14:	/* QnJ, IcP */
  		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi",
  			 le16_to_cpu(ver.hw_variant),
  			 le16_to_cpu(ver.hw_revision),
@@@ -2204,8 -2196,6 +2204,8 @@@
  		break;
  	case 0x11:	/* JfP */
  	case 0x12:	/* ThP */
 +	case 0x13:	/* HrP */
 +	case 0x14:	/* QnJ, IcP */
  		snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc",
  			 le16_to_cpu(ver.hw_variant),
  			 le16_to_cpu(ver.hw_revision),
diff --combined drivers/infiniband/core/cma.c
index 915bbd867b61,a5367c5efbe7..66f203730e80
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@@ -1334,7 -1334,7 +1334,7 @@@ static bool validate_ipv6_net_dev(struc
  			   IPV6_ADDR_LINKLOCAL;
  	struct rt6_info *rt = rt6_lookup(dev_net(net_dev), &dst_addr->sin6_addr,
  					 &src_addr->sin6_addr, net_dev->ifindex,
 -					 strict);
 +					 NULL, strict);
  	bool ret;
  
  	if (!rt)
@@@ -3069,7 -3069,8 +3069,8 @@@ static int cma_port_is_unique(struct rd
  			continue;
  
  		/* different dest port -> unique */
- 		if (!cma_any_port(cur_daddr) &&
+ 		if (!cma_any_port(daddr) &&
+ 		    !cma_any_port(cur_daddr) &&
  		    (dport != cur_dport))
  			continue;
  
@@@ -3080,7 -3081,8 +3081,8 @@@
  			continue;
  
  		/* different dst address -> unique */
- 		if (!cma_any_addr(cur_daddr) &&
+ 		if (!cma_any_addr(daddr) &&
+ 		    !cma_any_addr(cur_daddr) &&
  		    cma_addr_cmp(daddr, cur_daddr))
  			continue;
  
@@@ -3378,13 -3380,13 +3380,13 @@@ int rdma_bind_addr(struct rdma_cm_id *i
  		}
  #endif
  	}
+ 	daddr = cma_dst_addr(id_priv);
+ 	daddr->sa_family = addr->sa_family;
+ 
  	ret = cma_get_port(id_priv);
  	if (ret)
  		goto err2;
  
- 	daddr = cma_dst_addr(id_priv);
- 	daddr->sa_family = addr->sa_family;
- 
  	return 0;
  err2:
  	if (id_priv->cma_dev)
@@@ -4173,6 -4175,9 +4175,9 @@@ int rdma_join_multicast(struct rdma_cm_
  	struct cma_multicast *mc;
  	int ret;
  
+ 	if (!id->device)
+ 		return -EINVAL;
+ 
  	id_priv = container_of(id, struct rdma_id_private, id);
  	if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
  	    !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
@@@ -4549,7 -4554,6 +4554,7 @@@ static struct pernet_operations cma_per
  	.exit = cma_exit_net,
  	.id = &cma_pernet_id,
  	.size = sizeof(struct cma_pernet),
 +	.async = true,
  };
  
  static int __init cma_init(void)
diff --combined drivers/infiniband/hw/mlx5/cq.c
index c4c7b82f4ac1,15457c9569a7..94a27d89a303
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@@ -64,9 -64,14 +64,9 @@@ static void mlx5_ib_cq_event(struct mlx
  	}
  }
  
 -static void *get_cqe_from_buf(struct mlx5_ib_cq_buf *buf, int n, int size)
 -{
 -	return mlx5_buf_offset(&buf->buf, n * size);
 -}
 -
  static void *get_cqe(struct mlx5_ib_cq *cq, int n)
  {
 -	return get_cqe_from_buf(&cq->buf, n, cq->mcq.cqe_sz);
 +	return mlx5_frag_buf_get_wqe(&cq->buf.fbc, n);
  }
  
  static u8 sw_ownership_bit(int n, int nent)
@@@ -221,7 -226,6 +221,6 @@@ static void handle_responder(struct ib_
  		wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey);
  		break;
  	}
- 	wc->slid	   = be16_to_cpu(cqe->slid);
  	wc->src_qp	   = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
  	wc->dlid_path_bits = cqe->ml_path;
  	g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
@@@ -236,10 -240,12 +235,12 @@@
  	}
  
  	if (ll != IB_LINK_LAYER_ETHERNET) {
+ 		wc->slid = be16_to_cpu(cqe->slid);
  		wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
  		return;
  	}
  
+ 	wc->slid = 0;
  	vlan_present = cqe->l4_l3_hdr_type & 0x1;
  	roce_packet_type   = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
  	if (vlan_present) {
@@@ -398,7 -404,7 +399,7 @@@ static void handle_atomics(struct mlx5_
  
  static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
  {
 -	mlx5_buf_free(dev->mdev, &buf->buf);
 +	mlx5_frag_buf_free(dev->mdev, &buf->fbc.frag_buf);
  }
  
  static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe,
@@@ -719,25 -725,12 +720,25 @@@ int mlx5_ib_arm_cq(struct ib_cq *ibcq, 
  	return ret;
  }
  
 -static int alloc_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf,
 -			int nent, int cqe_size)
 +static int alloc_cq_frag_buf(struct mlx5_ib_dev *dev,
 +			     struct mlx5_ib_cq_buf *buf,
 +			     int nent,
 +			     int cqe_size)
  {
 +	struct mlx5_frag_buf_ctrl *c = &buf->fbc;
 +	struct mlx5_frag_buf *frag_buf = &c->frag_buf;
 +	u32 cqc_buff[MLX5_ST_SZ_DW(cqc)] = {0};
  	int err;
  
 -	err = mlx5_buf_alloc(dev->mdev, nent * cqe_size, &buf->buf);
 +	MLX5_SET(cqc, cqc_buff, log_cq_size, ilog2(cqe_size));
 +	MLX5_SET(cqc, cqc_buff, cqe_sz, (cqe_size == 128) ? 1 : 0);
 +
 +	mlx5_core_init_cq_frag_buf(&buf->fbc, cqc_buff);
 +
 +	err = mlx5_frag_buf_alloc_node(dev->mdev,
 +				       nent * cqe_size,
 +				       frag_buf,
 +				       dev->mdev->priv.numa_node);
  	if (err)
  		return err;
  
@@@ -870,15 -863,14 +871,15 @@@ static void destroy_cq_user(struct mlx5
  	ib_umem_release(cq->buf.umem);
  }
  
 -static void init_cq_buf(struct mlx5_ib_cq *cq, struct mlx5_ib_cq_buf *buf)
 +static void init_cq_frag_buf(struct mlx5_ib_cq *cq,
 +			     struct mlx5_ib_cq_buf *buf)
  {
  	int i;
  	void *cqe;
  	struct mlx5_cqe64 *cqe64;
  
  	for (i = 0; i < buf->nent; i++) {
 -		cqe = get_cqe_from_buf(buf, i, buf->cqe_size);
 +		cqe = get_cqe(cq, i);
  		cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64;
  		cqe64->op_own = MLX5_CQE_INVALID << 4;
  	}
@@@ -900,15 -892,14 +901,15 @@@ static int create_cq_kernel(struct mlx5
  	cq->mcq.arm_db     = cq->db.db + 1;
  	cq->mcq.cqe_sz = cqe_size;
  
 -	err = alloc_cq_buf(dev, &cq->buf, entries, cqe_size);
 +	err = alloc_cq_frag_buf(dev, &cq->buf, entries, cqe_size);
  	if (err)
  		goto err_db;
  
 -	init_cq_buf(cq, &cq->buf);
 +	init_cq_frag_buf(cq, &cq->buf);
  
  	*inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
 -		 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * cq->buf.buf.npages;
 +		 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) *
 +		 cq->buf.fbc.frag_buf.npages;
  	*cqb = kvzalloc(*inlen, GFP_KERNEL);
  	if (!*cqb) {
  		err = -ENOMEM;
@@@ -916,12 -907,11 +917,12 @@@
  	}
  
  	pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, *cqb, pas);
 -	mlx5_fill_page_array(&cq->buf.buf, pas);
 +	mlx5_fill_page_frag_array(&cq->buf.fbc.frag_buf, pas);
  
  	cqc = MLX5_ADDR_OF(create_cq_in, *cqb, cq_context);
  	MLX5_SET(cqc, cqc, log_page_size,
 -		 cq->buf.buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
 +		 cq->buf.fbc.frag_buf.page_shift -
 +		 MLX5_ADAPTER_PAGE_SHIFT);
  
  	*index = dev->mdev->priv.uar->index;
  
@@@ -1188,7 -1178,12 +1189,12 @@@ static int resize_user(struct mlx5_ib_d
  	if (ucmd.reserved0 || ucmd.reserved1)
  		return -EINVAL;
  
- 	umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size,
+ 	/* check multiplication overflow */
+ 	if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1)
+ 		return -EINVAL;
+ 
+ 	umem = ib_umem_get(context, ucmd.buf_addr,
+ 			   (size_t)ucmd.cqe_size * entries,
  			   IB_ACCESS_LOCAL_WRITE, 1);
  	if (IS_ERR(umem)) {
  		err = PTR_ERR(umem);
@@@ -1218,11 -1213,11 +1224,11 @@@ static int resize_kernel(struct mlx5_ib
  	if (!cq->resize_buf)
  		return -ENOMEM;
  
 -	err = alloc_cq_buf(dev, cq->resize_buf, entries, cqe_size);
 +	err = alloc_cq_frag_buf(dev, cq->resize_buf, entries, cqe_size);
  	if (err)
  		goto ex;
  
 -	init_cq_buf(cq, cq->resize_buf);
 +	init_cq_frag_buf(cq, cq->resize_buf);
  
  	return 0;
  
@@@ -1267,8 -1262,9 +1273,8 @@@ static int copy_resize_cqes(struct mlx5
  	}
  
  	while ((scqe64->op_own >> 4) != MLX5_CQE_RESIZE_CQ) {
 -		dcqe = get_cqe_from_buf(cq->resize_buf,
 -					(i + 1) & (cq->resize_buf->nent),
 -					dsize);
 +		dcqe = mlx5_frag_buf_get_wqe(&cq->resize_buf->fbc,
 +					     (i + 1) & cq->resize_buf->nent);
  		dcqe64 = dsize == 64 ? dcqe : dcqe + 64;
  		sw_own = sw_ownership_bit(i + 1, cq->resize_buf->nent);
  		memcpy(dcqe, scqe, dsize);
@@@ -1334,11 -1330,8 +1340,11 @@@ int mlx5_ib_resize_cq(struct ib_cq *ibc
  		cqe_size = 64;
  		err = resize_kernel(dev, cq, entries, cqe_size);
  		if (!err) {
 -			npas = cq->resize_buf->buf.npages;
 -			page_shift = cq->resize_buf->buf.page_shift;
 +			struct mlx5_frag_buf_ctrl *c;
 +
 +			c = &cq->resize_buf->fbc;
 +			npas = c->frag_buf.npages;
 +			page_shift = c->frag_buf.page_shift;
  		}
  	}
  
@@@ -1359,8 -1352,7 +1365,8 @@@
  		mlx5_ib_populate_pas(dev, cq->resize_umem, page_shift,
  				     pas, 0);
  	else
 -		mlx5_fill_page_array(&cq->resize_buf->buf, pas);
 +		mlx5_fill_page_frag_array(&cq->resize_buf->fbc.frag_buf,
 +					  pas);
  
  	MLX5_SET(modify_cq_in, in,
  		 modify_field_select_resize_field_select.resize_field_select.resize_field_select,
diff --combined drivers/infiniband/hw/mlx5/ib_rep.c
index 61cc3d7db257,000000000000..0e04fdddf670
mode 100644,000000..100644
--- a/drivers/infiniband/hw/mlx5/ib_rep.c
+++ b/drivers/infiniband/hw/mlx5/ib_rep.c
@@@ -1,189 -1,0 +1,192 @@@
 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 +/*
 + * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
 + */
 +
 +#include "ib_rep.h"
 +
 +static const struct mlx5_ib_profile rep_profile = {
 +	STAGE_CREATE(MLX5_IB_STAGE_INIT,
 +		     mlx5_ib_stage_init_init,
 +		     mlx5_ib_stage_init_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
 +		     mlx5_ib_stage_rep_flow_db_init,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_CAPS,
 +		     mlx5_ib_stage_caps_init,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
 +		     mlx5_ib_stage_rep_non_default_cb,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_ROCE,
 +		     mlx5_ib_stage_rep_roce_init,
 +		     mlx5_ib_stage_rep_roce_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
 +		     mlx5_ib_stage_dev_res_init,
 +		     mlx5_ib_stage_dev_res_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
 +		     mlx5_ib_stage_counters_init,
 +		     mlx5_ib_stage_counters_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_BFREG,
 +		     mlx5_ib_stage_bfrag_init,
 +		     mlx5_ib_stage_bfrag_cleanup),
++	STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
++		     NULL,
++		     mlx5_ib_stage_pre_ib_reg_umr_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
 +		     mlx5_ib_stage_ib_reg_init,
 +		     mlx5_ib_stage_ib_reg_cleanup),
- 	STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES,
- 		     mlx5_ib_stage_umr_res_init,
- 		     mlx5_ib_stage_umr_res_cleanup),
++	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
++		     mlx5_ib_stage_post_ib_reg_umr_init,
++		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_CLASS_ATTR,
 +		     mlx5_ib_stage_class_attr_init,
 +		     NULL),
 +};
 +
 +static int
 +mlx5_ib_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 +{
 +	return 0;
 +}
 +
 +static void
 +mlx5_ib_nic_rep_unload(struct mlx5_eswitch_rep *rep)
 +{
 +	rep->rep_if[REP_IB].priv = NULL;
 +}
 +
 +static int
 +mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 +{
 +	struct mlx5_ib_dev *ibdev;
 +
 +	ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev));
 +	if (!ibdev)
 +		return -ENOMEM;
 +
 +	ibdev->rep = rep;
 +	ibdev->mdev = dev;
 +	ibdev->num_ports = max(MLX5_CAP_GEN(dev, num_ports),
 +			       MLX5_CAP_GEN(dev, num_vhca_ports));
 +	if (!__mlx5_ib_add(ibdev, &rep_profile))
 +		return -EINVAL;
 +
 +	rep->rep_if[REP_IB].priv = ibdev;
 +
 +	return 0;
 +}
 +
 +static void
 +mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
 +{
 +	struct mlx5_ib_dev *dev;
 +
 +	if (!rep->rep_if[REP_IB].priv)
 +		return;
 +
 +	dev = mlx5_ib_rep_to_dev(rep);
 +	__mlx5_ib_remove(dev, dev->profile, MLX5_IB_STAGE_MAX);
 +	rep->rep_if[REP_IB].priv = NULL;
 +}
 +
 +static void *mlx5_ib_vport_get_proto_dev(struct mlx5_eswitch_rep *rep)
 +{
 +	return mlx5_ib_rep_to_dev(rep);
 +}
 +
 +static void mlx5_ib_rep_register_vf_vports(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_eswitch *esw   = dev->mdev->priv.eswitch;
 +	int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
 +	int vport;
 +
 +	for (vport = 1; vport < total_vfs; vport++) {
 +		struct mlx5_eswitch_rep_if rep_if = {};
 +
 +		rep_if.load = mlx5_ib_vport_rep_load;
 +		rep_if.unload = mlx5_ib_vport_rep_unload;
 +		rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
 +		mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_IB);
 +	}
 +}
 +
 +static void mlx5_ib_rep_unregister_vf_vports(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_eswitch *esw   = dev->mdev->priv.eswitch;
 +	int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
 +	int vport;
 +
 +	for (vport = 1; vport < total_vfs; vport++)
 +		mlx5_eswitch_unregister_vport_rep(esw, vport, REP_IB);
 +}
 +
 +void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
 +	struct mlx5_eswitch_rep_if rep_if = {};
 +
 +	rep_if.load = mlx5_ib_nic_rep_load;
 +	rep_if.unload = mlx5_ib_nic_rep_unload;
 +	rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
 +	rep_if.priv = dev;
 +
 +	mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_IB);
 +
 +	mlx5_ib_rep_register_vf_vports(dev);
 +}
 +
 +void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_eswitch *esw   = dev->mdev->priv.eswitch;
 +
 +	mlx5_ib_rep_unregister_vf_vports(dev); /* VFs vports */
 +	mlx5_eswitch_unregister_vport_rep(esw, 0, REP_IB); /* UPLINK PF*/
 +}
 +
 +u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw)
 +{
 +	return mlx5_eswitch_mode(esw);
 +}
 +
 +struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
 +					  int vport_index)
 +{
 +	return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_IB);
 +}
 +
 +struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
 +					  int vport_index)
 +{
 +	return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_ETH);
 +}
 +
 +struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw)
 +{
 +	return mlx5_eswitch_uplink_get_proto_dev(esw, REP_IB);
 +}
 +
 +struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw, int vport)
 +{
 +	return mlx5_eswitch_vport_rep(esw, vport);
 +}
 +
 +int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
 +			      struct mlx5_ib_sq *sq)
 +{
 +	struct mlx5_flow_handle *flow_rule;
 +	struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
 +
 +	if (!dev->rep)
 +		return 0;
 +
 +	flow_rule =
 +		mlx5_eswitch_add_send_to_vport_rule(esw,
 +						    dev->rep->vport,
 +						    sq->base.mqp.qpn);
 +	if (IS_ERR(flow_rule))
 +		return PTR_ERR(flow_rule);
 +	sq->flow_rule = flow_rule;
 +
 +	return 0;
 +}
diff --combined drivers/infiniband/hw/mlx5/main.c
index d9474b95d8e5,da091de4e69d..390e4375647e
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@@ -57,9 -57,7 +57,9 @@@
  #include <linux/in.h>
  #include <linux/etherdevice.h>
  #include "mlx5_ib.h"
 +#include "ib_rep.h"
  #include "cmd.h"
 +#include <linux/mlx5/fs_helpers.h>
  
  #define DRIVER_NAME "mlx5_ib"
  #define DRIVER_VERSION "5.0-0"
@@@ -132,7 -130,7 +132,7 @@@ static int get_port_state(struct ib_dev
  	int ret;
  
  	memset(&attr, 0, sizeof(attr));
 -	ret = mlx5_ib_query_port(ibdev, port_num, &attr);
 +	ret = ibdev->query_port(ibdev, port_num, &attr);
  	if (!ret)
  		*state = attr.state;
  	return ret;
@@@ -156,19 -154,10 +156,19 @@@ static int mlx5_netdev_event(struct not
  	case NETDEV_REGISTER:
  	case NETDEV_UNREGISTER:
  		write_lock(&roce->netdev_lock);
 -
 -		if (ndev->dev.parent == &mdev->pdev->dev)
 -			roce->netdev = (event == NETDEV_UNREGISTER) ?
 +		if (ibdev->rep) {
 +			struct mlx5_eswitch *esw = ibdev->mdev->priv.eswitch;
 +			struct net_device *rep_ndev;
 +
 +			rep_ndev = mlx5_ib_get_rep_netdev(esw,
 +							  ibdev->rep->vport);
 +			if (rep_ndev == ndev)
 +				roce->netdev = (event == NETDEV_UNREGISTER) ?
  					NULL : ndev;
 +		} else if (ndev->dev.parent == &ibdev->mdev->pdev->dev) {
 +			roce->netdev = (event == NETDEV_UNREGISTER) ?
 +				NULL : ndev;
 +		}
  		write_unlock(&roce->netdev_lock);
  		break;
  
@@@ -256,12 -245,16 +256,16 @@@ struct mlx5_core_dev *mlx5_ib_get_nativ
  	struct mlx5_ib_multiport_info *mpi;
  	struct mlx5_ib_port *port;
  
+ 	if (!mlx5_core_mp_enabled(ibdev->mdev) ||
+ 	    ll != IB_LINK_LAYER_ETHERNET) {
+ 		if (native_port_num)
+ 			*native_port_num = ib_port_num;
+ 		return ibdev->mdev;
+ 	}
+ 
  	if (native_port_num)
  		*native_port_num = 1;
  
- 	if (!mlx5_core_mp_enabled(ibdev->mdev) || ll != IB_LINK_LAYER_ETHERNET)
- 		return ibdev->mdev;
- 
  	port = &ibdev->port[ib_port_num - 1];
  	if (!port)
  		return NULL;
@@@ -1279,22 -1272,6 +1283,22 @@@ int mlx5_ib_query_port(struct ib_devic
  	return ret;
  }
  
 +static int mlx5_ib_rep_query_port(struct ib_device *ibdev, u8 port,
 +				  struct ib_port_attr *props)
 +{
 +	int ret;
 +
 +	/* Only link layer == ethernet is valid for representors */
 +	ret = mlx5_query_port_roce(ibdev, port, props);
 +	if (ret || !props)
 +		return ret;
 +
 +	/* We don't support GIDS */
 +	props->gid_tbl_len = 0;
 +
 +	return ret;
 +}
 +
  static int mlx5_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
  			     union ib_gid *gid)
  {
@@@ -2313,9 -2290,11 +2317,9 @@@ static void set_tos(void *outer_c, voi
  		   offsetof(typeof(filter), field) -\
  		   sizeof(filter.field))
  
 -#define IPV4_VERSION 4
 -#define IPV6_VERSION 6
  static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
  			   u32 *match_v, const union ib_flow_spec *ib_spec,
 -			   u32 *tag_id, bool *is_drop)
 +			   struct mlx5_flow_act *action)
  {
  	void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
  					   misc_parameters);
@@@ -2398,7 -2377,7 +2402,7 @@@
  			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
  				 ip_version, 0xf);
  			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
 -				 ip_version, IPV4_VERSION);
 +				 ip_version, MLX5_FS_IPV4_VERSION);
  		} else {
  			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
  				 ethertype, 0xffff);
@@@ -2437,7 -2416,7 +2441,7 @@@
  			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
  				 ip_version, 0xf);
  			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
 -				 ip_version, IPV6_VERSION);
 +				 ip_version, MLX5_FS_IPV6_VERSION);
  		} else {
  			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
  				 ethertype, 0xffff);
@@@ -2533,14 -2512,13 +2537,14 @@@
  		if (ib_spec->flow_tag.tag_id >= BIT(24))
  			return -EINVAL;
  
 -		*tag_id = ib_spec->flow_tag.tag_id;
 +		action->flow_tag = ib_spec->flow_tag.tag_id;
 +		action->has_flow_tag = true;
  		break;
  	case IB_FLOW_SPEC_ACTION_DROP:
  		if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
  					 LAST_DROP_FIELD))
  			return -EOPNOTSUPP;
 -		*is_drop = true;
 +		action->action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
  		break;
  	default:
  		return -EINVAL;
@@@ -2657,7 -2635,7 +2661,7 @@@ static int mlx5_ib_destroy_flow(struct 
  							  ibflow);
  	struct mlx5_ib_flow_handler *iter, *tmp;
  
 -	mutex_lock(&dev->flow_db.lock);
 +	mutex_lock(&dev->flow_db->lock);
  
  	list_for_each_entry_safe(iter, tmp, &handler->list, list) {
  		mlx5_del_flow_rules(iter->rule);
@@@ -2668,7 -2646,7 +2672,7 @@@
  
  	mlx5_del_flow_rules(handler->rule);
  	put_flow_table(dev, handler->prio, true);
 -	mutex_unlock(&dev->flow_db.lock);
 +	mutex_unlock(&dev->flow_db->lock);
  
  	kfree(handler);
  
@@@ -2717,7 -2695,7 +2721,7 @@@ static struct mlx5_ib_flow_prio *get_fl
  					     MLX5_FLOW_NAMESPACE_BYPASS);
  		num_entries = MLX5_FS_MAX_ENTRIES;
  		num_groups = MLX5_FS_MAX_TYPES;
 -		prio = &dev->flow_db.prios[priority];
 +		prio = &dev->flow_db->prios[priority];
  	} else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
  		   flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
  		ns = mlx5_get_flow_namespace(dev->mdev,
@@@ -2725,7 -2703,7 +2729,7 @@@
  		build_leftovers_ft_param(&priority,
  					 &num_entries,
  					 &num_groups);
 -		prio = &dev->flow_db.prios[MLX5_IB_FLOW_LEFTOVERS_PRIO];
 +		prio = &dev->flow_db->prios[MLX5_IB_FLOW_LEFTOVERS_PRIO];
  	} else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
  		if (!MLX5_CAP_FLOWTABLE(dev->mdev,
  					allow_sniffer_and_nic_rx_shared_tir))
@@@ -2735,7 -2713,7 +2739,7 @@@
  					     MLX5_FLOW_NAMESPACE_SNIFFER_RX :
  					     MLX5_FLOW_NAMESPACE_SNIFFER_TX);
  
 -		prio = &dev->flow_db.sniffer[ft_type];
 +		prio = &dev->flow_db->sniffer[ft_type];
  		priority = 0;
  		num_entries = 1;
  		num_groups = 1;
@@@ -2793,11 -2771,13 +2797,11 @@@ static struct mlx5_ib_flow_handler *_cr
  {
  	struct mlx5_flow_table	*ft = ft_prio->flow_table;
  	struct mlx5_ib_flow_handler *handler;
 -	struct mlx5_flow_act flow_act = {0};
 +	struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
  	struct mlx5_flow_spec *spec;
  	struct mlx5_flow_destination *rule_dst = dst;
  	const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr);
  	unsigned int spec_index;
 -	u32 flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
 -	bool is_drop = false;
  	int err = 0;
  	int dest_num = 1;
  
@@@ -2816,7 -2796,7 +2820,7 @@@
  	for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
  		err = parse_flow_attr(dev->mdev, spec->match_criteria,
  				      spec->match_value,
 -				      ib_flow, &flow_tag, &is_drop);
 +				      ib_flow, &flow_act);
  		if (err < 0)
  			goto free;
  
@@@ -2826,20 -2806,9 +2830,20 @@@
  	if (!flow_is_multicast_only(flow_attr))
  		set_underlay_qp(dev, spec, underlay_qpn);
  
 +	if (dev->rep) {
 +		void *misc;
 +
 +		misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
 +				    misc_parameters);
 +		MLX5_SET(fte_match_set_misc, misc, source_port,
 +			 dev->rep->vport);
 +		misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
 +				    misc_parameters);
 +		MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
 +	}
 +
  	spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
 -	if (is_drop) {
 -		flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
 +	if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
  		rule_dst = NULL;
  		dest_num = 0;
  	} else {
@@@ -2847,14 -2816,15 +2851,14 @@@
  		    MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
  	}
  
 -	if (flow_tag != MLX5_FS_DEFAULT_FLOW_TAG &&
 +	if (flow_act.has_flow_tag &&
  	    (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
  	     flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
  		mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
 -			     flow_tag, flow_attr->type);
 +			     flow_act.flow_tag, flow_attr->type);
  		err = -EINVAL;
  		goto free;
  	}
 -	flow_act.flow_tag = flow_tag;
  	handler->rule = mlx5_add_flow_rules(ft, spec,
  					    &flow_act,
  					    rule_dst, dest_num);
@@@ -3033,7 -3003,7 +3037,7 @@@ static struct ib_flow *mlx5_ib_create_f
  	if (!dst)
  		return ERR_PTR(-ENOMEM);
  
 -	mutex_lock(&dev->flow_db.lock);
 +	mutex_lock(&dev->flow_db->lock);
  
  	ft_prio = get_flow_table(dev, flow_attr, MLX5_IB_FT_RX);
  	if (IS_ERR(ft_prio)) {
@@@ -3082,7 -3052,7 +3086,7 @@@
  		goto destroy_ft;
  	}
  
 -	mutex_unlock(&dev->flow_db.lock);
 +	mutex_unlock(&dev->flow_db->lock);
  	kfree(dst);
  
  	return &handler->ibflow;
@@@ -3092,7 -3062,7 +3096,7 @@@ destroy_ft
  	if (ft_prio_tx)
  		put_flow_table(dev, ft_prio_tx, false);
  unlock:
 -	mutex_unlock(&dev->flow_db.lock);
 +	mutex_unlock(&dev->flow_db->lock);
  	kfree(dst);
  	kfree(handler);
  	return ERR_PTR(err);
@@@ -3297,7 -3267,7 +3301,7 @@@ static void mlx5_ib_handle_event(struc
  	struct mlx5_ib_dev *ibdev;
  	struct ib_event ibev;
  	bool fatal = false;
- 	u8 port = 0;
+ 	u8 port = (u8)work->param;
  
  	if (mlx5_core_is_mp_slave(work->dev)) {
  		ibdev = mlx5_ib_get_ibdev_from_mpi(work->context);
@@@ -3317,8 -3287,6 +3321,6 @@@
  	case MLX5_DEV_EVENT_PORT_UP:
  	case MLX5_DEV_EVENT_PORT_DOWN:
  	case MLX5_DEV_EVENT_PORT_INITIALIZED:
- 		port = (u8)work->param;
- 
  		/* In RoCE, port up/down events are handled in
  		 * mlx5_netdev_event().
  		 */
@@@ -3332,24 -3300,19 +3334,19 @@@
  
  	case MLX5_DEV_EVENT_LID_CHANGE:
  		ibev.event = IB_EVENT_LID_CHANGE;
- 		port = (u8)work->param;
  		break;
  
  	case MLX5_DEV_EVENT_PKEY_CHANGE:
  		ibev.event = IB_EVENT_PKEY_CHANGE;
- 		port = (u8)work->param;
- 
  		schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
  		break;
  
  	case MLX5_DEV_EVENT_GUID_CHANGE:
  		ibev.event = IB_EVENT_GID_CHANGE;
- 		port = (u8)work->param;
  		break;
  
  	case MLX5_DEV_EVENT_CLIENT_REREG:
  		ibev.event = IB_EVENT_CLIENT_REREGISTER;
- 		port = (u8)work->param;
  		break;
  	case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT:
  		schedule_work(&ibdev->delay_drop.delay_drop_work);
@@@ -3361,7 -3324,7 +3358,7 @@@
  	ibev.device	      = &ibdev->ib_dev;
  	ibev.element.port_num = port;
  
- 	if (port < 1 || port > ibdev->num_ports) {
+ 	if (!rdma_is_port_valid(&ibdev->ib_dev, port)) {
  		mlx5_ib_warn(ibdev, "warning: event on port %d\n", port);
  		goto out;
  	}
@@@ -3806,25 -3769,6 +3803,25 @@@ static int mlx5_port_immutable(struct i
  	return 0;
  }
  
 +static int mlx5_port_rep_immutable(struct ib_device *ibdev, u8 port_num,
 +				   struct ib_port_immutable *immutable)
 +{
 +	struct ib_port_attr attr;
 +	int err;
 +
 +	immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
 +
 +	err = ib_query_port(ibdev, port_num, &attr);
 +	if (err)
 +		return err;
 +
 +	immutable->pkey_tbl_len = attr.pkey_tbl_len;
 +	immutable->gid_tbl_len = attr.gid_tbl_len;
 +	immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
 +
 +	return 0;
 +}
 +
  static void get_dev_fw_str(struct ib_device *ibdev, char *str)
  {
  	struct mlx5_ib_dev *dev =
@@@ -3855,7 -3799,7 +3852,7 @@@ static int mlx5_eth_lag_init(struct mlx
  		goto err_destroy_vport_lag;
  	}
  
 -	dev->flow_db.lag_demux_ft = ft;
 +	dev->flow_db->lag_demux_ft = ft;
  	return 0;
  
  err_destroy_vport_lag:
@@@ -3867,9 -3811,9 +3864,9 @@@ static void mlx5_eth_lag_cleanup(struc
  {
  	struct mlx5_core_dev *mdev = dev->mdev;
  
 -	if (dev->flow_db.lag_demux_ft) {
 -		mlx5_destroy_flow_table(dev->flow_db.lag_demux_ft);
 -		dev->flow_db.lag_demux_ft = NULL;
 +	if (dev->flow_db->lag_demux_ft) {
 +		mlx5_destroy_flow_table(dev->flow_db->lag_demux_ft);
 +		dev->flow_db->lag_demux_ft = NULL;
  
  		mlx5_cmd_destroy_vport_lag(mdev);
  	}
@@@ -3901,10 -3845,14 +3898,10 @@@ static int mlx5_enable_eth(struct mlx5_
  {
  	int err;
  
 -	err = mlx5_add_netdev_notifier(dev, port_num);
 -	if (err)
 -		return err;
 -
  	if (MLX5_CAP_GEN(dev->mdev, roce)) {
  		err = mlx5_nic_vport_enable_roce(dev->mdev);
  		if (err)
 -			goto err_unregister_netdevice_notifier;
 +			return err;
  	}
  
  	err = mlx5_eth_lag_init(dev);
@@@ -3917,6 -3865,8 +3914,6 @@@ err_disable_roce
  	if (MLX5_CAP_GEN(dev->mdev, roce))
  		mlx5_nic_vport_disable_roce(dev->mdev);
  
 -err_unregister_netdevice_notifier:
 -	mlx5_remove_netdev_notifier(dev, port_num);
  	return err;
  }
  
@@@ -4550,7 -4500,7 +4547,7 @@@ static void mlx5_ib_cleanup_multiport_m
  	mlx5_nic_vport_disable_roce(dev->mdev);
  }
  
 -static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
 +void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
  {
  	mlx5_ib_cleanup_multiport_master(dev);
  #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
@@@ -4559,7 -4509,7 +4556,7 @@@
  	kfree(dev->port);
  }
  
 -static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
  {
  	struct mlx5_core_dev *mdev = dev->mdev;
  	const char *name;
@@@ -4581,6 -4531,8 +4578,6 @@@
  		goto err_free_port;
  
  	if (!mlx5_core_mp_enabled(mdev)) {
 -		int i;
 -
  		for (i = 1; i <= dev->num_ports; i++) {
  			err = get_port_caps(dev, i);
  			if (err)
@@@ -4609,6 -4561,7 +4606,6 @@@
  		dev->mdev->priv.eq_table.num_comp_vectors;
  	dev->ib_dev.dev.parent		= &mdev->pdev->dev;
  
 -	mutex_init(&dev->flow_db.lock);
  	mutex_init(&dev->cap_mask_mutex);
  	INIT_LIST_HEAD(&dev->qp_list);
  	spin_lock_init(&dev->reset_flow_resource_lock);
@@@ -4629,38 -4582,7 +4626,38 @@@ err_free_port
  	return -ENOMEM;
  }
  
 -static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
 +static int mlx5_ib_stage_flow_db_init(struct mlx5_ib_dev *dev)
 +{
 +	dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL);
 +
 +	if (!dev->flow_db)
 +		return -ENOMEM;
 +
 +	mutex_init(&dev->flow_db->lock);
 +
 +	return 0;
 +}
 +
 +int mlx5_ib_stage_rep_flow_db_init(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_ib_dev *nic_dev;
 +
 +	nic_dev = mlx5_ib_get_uplink_ibdev(dev->mdev->priv.eswitch);
 +
 +	if (!nic_dev)
 +		return -EINVAL;
 +
 +	dev->flow_db = nic_dev->flow_db;
 +
 +	return 0;
 +}
 +
 +static void mlx5_ib_stage_flow_db_cleanup(struct mlx5_ib_dev *dev)
 +{
 +	kfree(dev->flow_db);
 +}
 +
 +int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
  {
  	struct mlx5_core_dev *mdev = dev->mdev;
  	int err;
@@@ -4701,6 -4623,7 +4698,6 @@@
  		(1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ);
  
  	dev->ib_dev.query_device	= mlx5_ib_query_device;
 -	dev->ib_dev.query_port		= mlx5_ib_query_port;
  	dev->ib_dev.get_link_layer	= mlx5_ib_port_link_layer;
  	dev->ib_dev.query_gid		= mlx5_ib_query_gid;
  	dev->ib_dev.add_gid		= mlx5_ib_add_gid;
@@@ -4743,6 -4666,7 +4740,6 @@@
  	dev->ib_dev.alloc_mr		= mlx5_ib_alloc_mr;
  	dev->ib_dev.map_mr_sg		= mlx5_ib_map_mr_sg;
  	dev->ib_dev.check_mr_status	= mlx5_ib_check_mr_status;
 -	dev->ib_dev.get_port_immutable  = mlx5_port_immutable;
  	dev->ib_dev.get_dev_fw_str      = get_dev_fw_str;
  	dev->ib_dev.get_vector_affinity	= mlx5_ib_get_vector_affinity;
  	if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads))
@@@ -4793,80 -4717,6 +4790,80 @@@
  	return 0;
  }
  
 +static int mlx5_ib_stage_non_default_cb(struct mlx5_ib_dev *dev)
 +{
 +	dev->ib_dev.get_port_immutable  = mlx5_port_immutable;
 +	dev->ib_dev.query_port		= mlx5_ib_query_port;
 +
 +	return 0;
 +}
 +
 +int mlx5_ib_stage_rep_non_default_cb(struct mlx5_ib_dev *dev)
 +{
 +	dev->ib_dev.get_port_immutable  = mlx5_port_rep_immutable;
 +	dev->ib_dev.query_port		= mlx5_ib_rep_query_port;
 +
 +	return 0;
 +}
 +
 +static int mlx5_ib_stage_common_roce_init(struct mlx5_ib_dev *dev,
 +					  u8 port_num)
 +{
 +	int i;
 +
 +	for (i = 0; i < dev->num_ports; i++) {
 +		dev->roce[i].dev = dev;
 +		dev->roce[i].native_port_num = i + 1;
 +		dev->roce[i].last_port_state = IB_PORT_DOWN;
 +	}
 +
 +	dev->ib_dev.get_netdev	= mlx5_ib_get_netdev;
 +	dev->ib_dev.create_wq	 = mlx5_ib_create_wq;
 +	dev->ib_dev.modify_wq	 = mlx5_ib_modify_wq;
 +	dev->ib_dev.destroy_wq	 = mlx5_ib_destroy_wq;
 +	dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
 +	dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
 +
 +	dev->ib_dev.uverbs_ex_cmd_mask |=
 +			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
 +			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
 +			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
 +			(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
 +			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
 +
 +	return mlx5_add_netdev_notifier(dev, port_num);
 +}
 +
 +static void mlx5_ib_stage_common_roce_cleanup(struct mlx5_ib_dev *dev)
 +{
 +	u8 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
 +
 +	mlx5_remove_netdev_notifier(dev, port_num);
 +}
 +
 +int mlx5_ib_stage_rep_roce_init(struct mlx5_ib_dev *dev)
 +{
 +	struct mlx5_core_dev *mdev = dev->mdev;
 +	enum rdma_link_layer ll;
 +	int port_type_cap;
 +	int err = 0;
 +	u8 port_num;
 +
 +	port_num = mlx5_core_native_port_num(dev->mdev) - 1;
 +	port_type_cap = MLX5_CAP_GEN(mdev, port_type);
 +	ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
 +
 +	if (ll == IB_LINK_LAYER_ETHERNET)
 +		err = mlx5_ib_stage_common_roce_init(dev, port_num);
 +
 +	return err;
 +}
 +
 +void mlx5_ib_stage_rep_roce_cleanup(struct mlx5_ib_dev *dev)
 +{
 +	mlx5_ib_stage_common_roce_cleanup(dev);
 +}
 +
  static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev)
  {
  	struct mlx5_core_dev *mdev = dev->mdev;
@@@ -4874,26 -4724,37 +4871,26 @@@
  	int port_type_cap;
  	u8 port_num;
  	int err;
 -	int i;
  
  	port_num = mlx5_core_native_port_num(dev->mdev) - 1;
  	port_type_cap = MLX5_CAP_GEN(mdev, port_type);
  	ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
  
  	if (ll == IB_LINK_LAYER_ETHERNET) {
 -		for (i = 0; i < dev->num_ports; i++) {
 -			dev->roce[i].dev = dev;
 -			dev->roce[i].native_port_num = i + 1;
 -			dev->roce[i].last_port_state = IB_PORT_DOWN;
 -		}
 +		err = mlx5_ib_stage_common_roce_init(dev, port_num);
 +		if (err)
 +			return err;
  
 -		dev->ib_dev.get_netdev	= mlx5_ib_get_netdev;
 -		dev->ib_dev.create_wq	 = mlx5_ib_create_wq;
 -		dev->ib_dev.modify_wq	 = mlx5_ib_modify_wq;
 -		dev->ib_dev.destroy_wq	 = mlx5_ib_destroy_wq;
 -		dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
 -		dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
 -		dev->ib_dev.uverbs_ex_cmd_mask |=
 -			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
 -			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
 -			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
 -			(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
 -			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
  		err = mlx5_enable_eth(dev, port_num);
  		if (err)
 -			return err;
 +			goto cleanup;
  	}
  
  	return 0;
 +cleanup:
 +	mlx5_ib_stage_common_roce_cleanup(dev);
 +
 +	return err;
  }
  
  static void mlx5_ib_stage_roce_cleanup(struct mlx5_ib_dev *dev)
@@@ -4909,16 -4770,16 +4906,16 @@@
  
  	if (ll == IB_LINK_LAYER_ETHERNET) {
  		mlx5_disable_eth(dev);
 -		mlx5_remove_netdev_notifier(dev, port_num);
 +		mlx5_ib_stage_common_roce_cleanup(dev);
  	}
  }
  
 -static int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev)
  {
  	return create_dev_resources(&dev->devr);
  }
  
 -static void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev)
 +void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev)
  {
  	destroy_dev_resources(&dev->devr);
  }
@@@ -4930,7 -4791,7 +4927,7 @@@ static int mlx5_ib_stage_odp_init(struc
  	return mlx5_ib_odp_init_one(dev);
  }
  
 -static int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev)
  {
  	if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) {
  		dev->ib_dev.get_hw_stats	= mlx5_ib_get_hw_stats;
@@@ -4942,7 -4803,7 +4939,7 @@@
  	return 0;
  }
  
 -static void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev)
 +void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev)
  {
  	if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
  		mlx5_ib_dealloc_counters(dev);
@@@ -4973,7 -4834,7 +4970,7 @@@ static void mlx5_ib_stage_uar_cleanup(s
  	mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar);
  }
  
 -static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
  {
  	int err;
  
@@@ -4988,30 -4849,30 +4985,30 @@@
  	return err;
  }
  
 -static void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev)
 +void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev)
  {
  	mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg);
  	mlx5_free_bfreg(dev->mdev, &dev->bfreg);
  }
  
 -static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
  {
  	return ib_register_device(&dev->ib_dev, NULL);
  }
  
- void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
 -static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
++void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
  {
- 	ib_unregister_device(&dev->ib_dev);
+ 	destroy_umrc_res(dev);
  }
  
- int mlx5_ib_stage_umr_res_init(struct mlx5_ib_dev *dev)
 -static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
++void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
  {
- 	return create_umr_res(dev);
+ 	ib_unregister_device(&dev->ib_dev);
  }
  
- void mlx5_ib_stage_umr_res_cleanup(struct mlx5_ib_dev *dev)
 -static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
++int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
  {
- 	destroy_umrc_res(dev);
+ 	return create_umr_res(dev);
  }
  
  static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev)
@@@ -5026,7 -4887,7 +5023,7 @@@ static void mlx5_ib_stage_delay_drop_cl
  	cancel_delay_drop(dev);
  }
  
 -static int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev)
 +int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev)
  {
  	int err;
  	int i;
@@@ -5041,21 -4902,9 +5038,21 @@@
  	return 0;
  }
  
 -static void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
 -			     const struct mlx5_ib_profile *profile,
 -			     int stage)
 +static int mlx5_ib_stage_rep_reg_init(struct mlx5_ib_dev *dev)
 +{
 +	mlx5_ib_register_vport_reps(dev);
 +
 +	return 0;
 +}
 +
 +static void mlx5_ib_stage_rep_reg_cleanup(struct mlx5_ib_dev *dev)
 +{
 +	mlx5_ib_unregister_vport_reps(dev);
 +}
 +
 +void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
 +		      const struct mlx5_ib_profile *profile,
 +		      int stage)
  {
  	/* Number of stages to cleanup */
  	while (stage) {
@@@ -5069,14 -4918,23 +5066,14 @@@
  
  static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num);
  
 -static void *__mlx5_ib_add(struct mlx5_core_dev *mdev,
 -			   const struct mlx5_ib_profile *profile)
 +void *__mlx5_ib_add(struct mlx5_ib_dev *dev,
 +		    const struct mlx5_ib_profile *profile)
  {
 -	struct mlx5_ib_dev *dev;
  	int err;
  	int i;
  
  	printk_once(KERN_INFO "%s", mlx5_version);
  
 -	dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
 -	if (!dev)
 -		return NULL;
 -
 -	dev->mdev = mdev;
 -	dev->num_ports = max(MLX5_CAP_GEN(mdev, num_ports),
 -			     MLX5_CAP_GEN(mdev, num_vhca_ports));
 -
  	for (i = 0; i < MLX5_IB_STAGE_MAX; i++) {
  		if (profile->stage[i].init) {
  			err = profile->stage[i].init(dev);
@@@ -5100,15 -4958,9 +5097,15 @@@ static const struct mlx5_ib_profile pf_
  	STAGE_CREATE(MLX5_IB_STAGE_INIT,
  		     mlx5_ib_stage_init_init,
  		     mlx5_ib_stage_init_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
 +		     mlx5_ib_stage_flow_db_init,
 +		     mlx5_ib_stage_flow_db_cleanup),
  	STAGE_CREATE(MLX5_IB_STAGE_CAPS,
  		     mlx5_ib_stage_caps_init,
  		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
 +		     mlx5_ib_stage_non_default_cb,
 +		     NULL),
  	STAGE_CREATE(MLX5_IB_STAGE_ROCE,
  		     mlx5_ib_stage_roce_init,
  		     mlx5_ib_stage_roce_cleanup),
@@@ -5130,12 -4982,15 +5127,15 @@@
  	STAGE_CREATE(MLX5_IB_STAGE_BFREG,
  		     mlx5_ib_stage_bfrag_init,
  		     mlx5_ib_stage_bfrag_cleanup),
+ 	STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
+ 		     NULL,
+ 		     mlx5_ib_stage_pre_ib_reg_umr_cleanup),
  	STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
  		     mlx5_ib_stage_ib_reg_init,
  		     mlx5_ib_stage_ib_reg_cleanup),
- 	STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES,
- 		     mlx5_ib_stage_umr_res_init,
- 		     mlx5_ib_stage_umr_res_cleanup),
+ 	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
+ 		     mlx5_ib_stage_post_ib_reg_umr_init,
+ 		     NULL),
  	STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
  		     mlx5_ib_stage_delay_drop_init,
  		     mlx5_ib_stage_delay_drop_cleanup),
@@@ -5144,48 -4999,6 +5144,51 @@@
  		     NULL),
  };
  
 +static const struct mlx5_ib_profile nic_rep_profile = {
 +	STAGE_CREATE(MLX5_IB_STAGE_INIT,
 +		     mlx5_ib_stage_init_init,
 +		     mlx5_ib_stage_init_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
 +		     mlx5_ib_stage_flow_db_init,
 +		     mlx5_ib_stage_flow_db_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_CAPS,
 +		     mlx5_ib_stage_caps_init,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
 +		     mlx5_ib_stage_rep_non_default_cb,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_ROCE,
 +		     mlx5_ib_stage_rep_roce_init,
 +		     mlx5_ib_stage_rep_roce_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
 +		     mlx5_ib_stage_dev_res_init,
 +		     mlx5_ib_stage_dev_res_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
 +		     mlx5_ib_stage_counters_init,
 +		     mlx5_ib_stage_counters_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_UAR,
 +		     mlx5_ib_stage_uar_init,
 +		     mlx5_ib_stage_uar_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_BFREG,
 +		     mlx5_ib_stage_bfrag_init,
 +		     mlx5_ib_stage_bfrag_cleanup),
++	STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
++		     NULL,
++		     mlx5_ib_stage_pre_ib_reg_umr_cleanup),
 +	STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
 +		     mlx5_ib_stage_ib_reg_init,
 +		     mlx5_ib_stage_ib_reg_cleanup),
- 	STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES,
- 		     mlx5_ib_stage_umr_res_init,
- 		     mlx5_ib_stage_umr_res_cleanup),
++	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
++		     mlx5_ib_stage_post_ib_reg_umr_init,
++		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_CLASS_ATTR,
 +		     mlx5_ib_stage_class_attr_init,
 +		     NULL),
 +	STAGE_CREATE(MLX5_IB_STAGE_REP_REG,
 +		     mlx5_ib_stage_rep_reg_init,
 +		     mlx5_ib_stage_rep_reg_cleanup),
 +};
 +
  static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num)
  {
  	struct mlx5_ib_multiport_info *mpi;
@@@ -5231,11 -5044,8 +5234,11 @@@
  static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
  {
  	enum rdma_link_layer ll;
 +	struct mlx5_ib_dev *dev;
  	int port_type_cap;
  
 +	printk_once(KERN_INFO "%s", mlx5_version);
 +
  	port_type_cap = MLX5_CAP_GEN(mdev, port_type);
  	ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
  
@@@ -5245,22 -5055,7 +5248,22 @@@
  		return mlx5_ib_add_slave_port(mdev, port_num);
  	}
  
 -	return __mlx5_ib_add(mdev, &pf_profile);
 +	dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
 +	if (!dev)
 +		return NULL;
 +
 +	dev->mdev = mdev;
 +	dev->num_ports = max(MLX5_CAP_GEN(mdev, num_ports),
 +			     MLX5_CAP_GEN(mdev, num_vhca_ports));
 +
 +	if (MLX5_VPORT_MANAGER(mdev) &&
 +	    mlx5_ib_eswitch_mode(mdev->priv.eswitch) == SRIOV_OFFLOADS) {
 +		dev->rep = mlx5_ib_vport_rep(mdev->priv.eswitch, 0);
 +
 +		return __mlx5_ib_add(dev, &nic_rep_profile);
 +	}
 +
 +	return __mlx5_ib_add(dev, &pf_profile);
  }
  
  static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
diff --combined drivers/infiniband/hw/mlx5/mlx5_ib.h
index e0bad28e0f09,a5272499b600..c33bf1523d67
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@@ -343,7 -343,6 +343,7 @@@ struct mlx5_ib_sq 
  	struct mlx5_ib_wq	*sq;
  	struct mlx5_ib_ubuffer  ubuffer;
  	struct mlx5_db		*doorbell;
 +	struct mlx5_flow_handle	*flow_rule;
  	u32			tisn;
  	u8			state;
  };
@@@ -372,7 -371,7 +372,7 @@@ struct mlx5_ib_qp 
  		struct mlx5_ib_rss_qp rss_qp;
  		struct mlx5_ib_dct dct;
  	};
 -	struct mlx5_buf		buf;
 +	struct mlx5_frag_buf	buf;
  
  	struct mlx5_db		db;
  	struct mlx5_ib_wq	rq;
@@@ -414,7 -413,7 +414,7 @@@
  };
  
  struct mlx5_ib_cq_buf {
 -	struct mlx5_buf		buf;
 +	struct mlx5_frag_buf_ctrl fbc;
  	struct ib_umem		*umem;
  	int			cqe_size;
  	int			nent;
@@@ -496,7 -495,7 +496,7 @@@ struct mlx5_ib_wc 
  struct mlx5_ib_srq {
  	struct ib_srq		ibsrq;
  	struct mlx5_core_srq	msrq;
 -	struct mlx5_buf		buf;
 +	struct mlx5_frag_buf	buf;
  	struct mlx5_db		db;
  	u64		       *wrid;
  	/* protect SRQ hanlding
@@@ -732,9 -731,7 +732,9 @@@ struct mlx5_ib_delay_drop 
  
  enum mlx5_ib_stages {
  	MLX5_IB_STAGE_INIT,
 +	MLX5_IB_STAGE_FLOW_DB,
  	MLX5_IB_STAGE_CAPS,
 +	MLX5_IB_STAGE_NON_DEFAULT_CB,
  	MLX5_IB_STAGE_ROCE,
  	MLX5_IB_STAGE_DEVICE_RESOURCES,
  	MLX5_IB_STAGE_ODP,
@@@ -742,11 -739,11 +742,12 @@@
  	MLX5_IB_STAGE_CONG_DEBUGFS,
  	MLX5_IB_STAGE_UAR,
  	MLX5_IB_STAGE_BFREG,
+ 	MLX5_IB_STAGE_PRE_IB_REG_UMR,
  	MLX5_IB_STAGE_IB_REG,
- 	MLX5_IB_STAGE_UMR_RESOURCES,
+ 	MLX5_IB_STAGE_POST_IB_REG_UMR,
  	MLX5_IB_STAGE_DELAY_DROP,
  	MLX5_IB_STAGE_CLASS_ATTR,
 +	MLX5_IB_STAGE_REP_REG,
  	MLX5_IB_STAGE_MAX,
  };
  
@@@ -801,7 -798,7 +802,7 @@@ struct mlx5_ib_dev 
  	struct srcu_struct      mr_srcu;
  	u32			null_mkey;
  #endif
 -	struct mlx5_ib_flow_db	flow_db;
 +	struct mlx5_ib_flow_db	*flow_db;
  	/* protect resources needed as part of reset flow */
  	spinlock_t		reset_flow_resource_lock;
  	struct list_head	qp_list;
@@@ -811,7 -808,6 +812,7 @@@
  	struct mlx5_sq_bfreg	fp_bfreg;
  	struct mlx5_ib_delay_drop	delay_drop;
  	const struct mlx5_ib_profile	*profile;
 +	struct mlx5_eswitch_rep		*rep;
  
  	/* protect the user_td */
  	struct mutex		lb_mutex;
@@@ -1054,31 -1050,6 +1055,31 @@@ static inline void mlx5_odp_populate_kl
  
  #endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
  
 +/* Needed for rep profile */
 +int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_rep_flow_db_init(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_rep_non_default_cb(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_rep_roce_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_rep_roce_cleanup(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev);
++void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev);
 +void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev);
- int mlx5_ib_stage_umr_res_init(struct mlx5_ib_dev *dev);
- void mlx5_ib_stage_umr_res_cleanup(struct mlx5_ib_dev *dev);
++int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev);
 +int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev);
 +void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
 +		      const struct mlx5_ib_profile *profile,
 +		      int stage);
 +void *__mlx5_ib_add(struct mlx5_ib_dev *dev,
 +		    const struct mlx5_ib_profile *profile);
 +
  int mlx5_ib_get_vf_config(struct ib_device *device, int vf,
  			  u8 port, struct ifla_vf_info *info);
  int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
diff --combined drivers/infiniband/hw/mlx5/mr.c
index a5fad3e87ff7,c51c602f06d6..95a36e9ea552
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@@ -587,7 -587,7 +587,7 @@@ static void clean_keys(struct mlx5_ib_d
  
  static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
  {
 -	if (!mlx5_debugfs_root)
 +	if (!mlx5_debugfs_root || dev->rep)
  		return;
  
  	debugfs_remove_recursive(dev->cache.root);
@@@ -600,7 -600,7 +600,7 @@@ static int mlx5_mr_cache_debugfs_init(s
  	struct mlx5_cache_ent *ent;
  	int i;
  
 -	if (!mlx5_debugfs_root)
 +	if (!mlx5_debugfs_root || dev->rep)
  		return 0;
  
  	cache->root = debugfs_create_dir("mr_cache", dev->mdev->priv.dbg_root);
@@@ -690,7 -690,6 +690,7 @@@ int mlx5_mr_cache_init(struct mlx5_ib_d
  			   MLX5_IB_UMR_OCTOWORD;
  		ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
  		if ((dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE) &&
 +		    !dev->rep &&
  		    mlx5_core_is_pf(dev->mdev))
  			ent->limit = dev->mdev->profile->mr_cache[i].limit;
  		else
@@@ -839,7 -838,8 +839,8 @@@ static int mr_umem_get(struct ib_pd *pd
  	*umem = ib_umem_get(pd->uobject->context, start, length,
  			    access_flags, 0);
  	err = PTR_ERR_OR_ZERO(*umem);
- 	if (err < 0) {
+ 	if (err) {
+ 		*umem = NULL;
  		mlx5_ib_err(dev, "umem get failed (%d)\n", err);
  		return err;
  	}
@@@ -1416,6 -1416,7 +1417,7 @@@ int mlx5_ib_rereg_user_mr(struct ib_mr 
  		if (err) {
  			mlx5_ib_warn(dev, "Failed to rereg UMR\n");
  			ib_umem_release(mr->umem);
+ 			mr->umem = NULL;
  			clean_mr(dev, mr);
  			return err;
  		}
@@@ -1499,14 -1500,11 +1501,11 @@@ static int clean_mr(struct mlx5_ib_dev 
  		u32 key = mr->mmkey.key;
  
  		err = destroy_mkey(dev, mr);
- 		kfree(mr);
  		if (err) {
  			mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
  				     key, err);
  			return err;
  		}
- 	} else {
- 		mlx5_mr_cache_free(dev, mr);
  	}
  
  	return 0;
@@@ -1549,6 -1547,11 +1548,11 @@@ static int dereg_mr(struct mlx5_ib_dev 
  		atomic_sub(npages, &dev->mdev->priv.reg_pages);
  	}
  
+ 	if (!mr->allocated_from_cache)
+ 		kfree(mr);
+ 	else
+ 		mlx5_mr_cache_free(dev, mr);
+ 
  	return 0;
  }
  
@@@ -1817,7 -1820,6 +1821,6 @@@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *m
  
  	mr->ibmr.iova = sg_dma_address(sg) + sg_offset;
  	mr->ibmr.length = 0;
- 	mr->ndescs = sg_nents;
  
  	for_each_sg(sgl, sg, sg_nents, i) {
  		if (unlikely(i >= mr->max_descs))
@@@ -1829,6 -1831,7 +1832,7 @@@
  
  		sg_offset = 0;
  	}
+ 	mr->ndescs = i;
  
  	if (sg_offset_p)
  		*sg_offset_p = sg_offset;
diff --combined drivers/infiniband/hw/mlx5/qp.c
index 0e67e3682bca,a2e1aa86e133..85c612ac547a
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@@ -36,7 -36,6 +36,7 @@@
  #include <rdma/ib_user_verbs.h>
  #include <linux/mlx5/fs.h>
  #include "mlx5_ib.h"
 +#include "ib_rep.h"
  
  /* not supported currently */
  static int wq_signature;
@@@ -1083,13 -1082,6 +1083,13 @@@ static void destroy_raw_packet_qp_tis(s
  	mlx5_core_destroy_tis(dev->mdev, sq->tisn);
  }
  
 +static void destroy_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
 +				       struct mlx5_ib_sq *sq)
 +{
 +	if (sq->flow_rule)
 +		mlx5_del_flow_rules(sq->flow_rule);
 +}
 +
  static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
  				   struct mlx5_ib_sq *sq, void *qpin,
  				   struct ib_pd *pd)
@@@ -1153,15 -1145,8 +1153,15 @@@
  	if (err)
  		goto err_umem;
  
 +	err = create_flow_rule_vport_sq(dev, sq);
 +	if (err)
 +		goto err_flow;
 +
  	return 0;
  
 +err_flow:
 +	mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
 +
  err_umem:
  	ib_umem_release(sq->ubuffer.umem);
  	sq->ubuffer.umem = NULL;
@@@ -1172,12 -1157,11 +1172,12 @@@
  static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
  				     struct mlx5_ib_sq *sq)
  {
 +	destroy_flow_rule_vport_sq(dev, sq);
  	mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
  	ib_umem_release(sq->ubuffer.umem);
  }
  
- static int get_rq_pas_size(void *qpc)
+ static size_t get_rq_pas_size(void *qpc)
  {
  	u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
  	u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
@@@ -1193,7 -1177,8 +1193,8 @@@
  }
  
  static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
- 				   struct mlx5_ib_rq *rq, void *qpin)
+ 				   struct mlx5_ib_rq *rq, void *qpin,
+ 				   size_t qpinlen)
  {
  	struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
  	__be64 *pas;
@@@ -1202,9 -1187,12 +1203,12 @@@
  	void *rqc;
  	void *wq;
  	void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
- 	int inlen;
+ 	size_t rq_pas_size = get_rq_pas_size(qpc);
+ 	size_t inlen;
  	int err;
- 	u32 rq_pas_size = get_rq_pas_size(qpc);
+ 
+ 	if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas))
+ 		return -EINVAL;
  
  	inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
  	in = kvzalloc(inlen, GFP_KERNEL);
@@@ -1279,10 -1267,6 +1283,10 @@@ static int create_raw_packet_qp_tir(str
  	if (tunnel_offload_en)
  		MLX5_SET(tirc, tirc, tunneled_offload_en, 1);
  
 +	if (dev->rep)
 +		MLX5_SET(tirc, tirc, self_lb_block,
 +			 MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST_);
 +
  	err = mlx5_core_create_tir(dev->mdev, in, inlen, &rq->tirn);
  
  	kvfree(in);
@@@ -1297,7 -1281,7 +1301,7 @@@ static void destroy_raw_packet_qp_tir(s
  }
  
  static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
- 				u32 *in,
+ 				u32 *in, size_t inlen,
  				struct ib_pd *pd)
  {
  	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
@@@ -1329,7 -1313,7 +1333,7 @@@
  			rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;
  		if (qp->flags & MLX5_IB_QP_PCI_WRITE_END_PADDING)
  			rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING;
- 		err = create_raw_packet_qp_rq(dev, rq, in);
+ 		err = create_raw_packet_qp_rq(dev, rq, in, inlen);
  		if (err)
  			goto err_destroy_sq;
  
@@@ -1574,10 -1558,6 +1578,10 @@@ static int create_rss_raw_qp_tir(struc
  	MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields);
  
  create_tir:
 +	if (dev->rep)
 +		MLX5_SET(tirc, tirc, self_lb_block,
 +			 MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST_);
 +
  	err = mlx5_core_create_tir(dev->mdev, in, inlen, &qp->rss_qp.tirn);
  
  	if (err)
@@@ -1608,6 -1588,7 +1612,7 @@@ static int create_qp_common(struct mlx5
  	u32 uidx = MLX5_IB_DEFAULT_UIDX;
  	struct mlx5_ib_create_qp ucmd;
  	struct mlx5_ib_qp_base *base;
+ 	int mlx5_st;
  	void *qpc;
  	u32 *in;
  	int err;
@@@ -1616,6 -1597,10 +1621,10 @@@
  	spin_lock_init(&qp->sq.lock);
  	spin_lock_init(&qp->rq.lock);
  
+ 	mlx5_st = to_mlx5_st(init_attr->qp_type);
+ 	if (mlx5_st < 0)
+ 		return -EINVAL;
+ 
  	if (init_attr->rwq_ind_tbl) {
  		if (!udata)
  			return -ENOSYS;
@@@ -1777,7 -1762,7 +1786,7 @@@
  
  	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
  
- 	MLX5_SET(qpc, qpc, st, to_mlx5_st(init_attr->qp_type));
+ 	MLX5_SET(qpc, qpc, st, mlx5_st);
  	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
  
  	if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)
@@@ -1891,11 -1876,16 +1900,16 @@@
  		}
  	}
  
+ 	if (inlen < 0) {
+ 		err = -EINVAL;
+ 		goto err;
+ 	}
+ 
  	if (init_attr->qp_type == IB_QPT_RAW_PACKET ||
  	    qp->flags & MLX5_IB_QP_UNDERLAY) {
  		qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
  		raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
- 		err = create_raw_packet_qp(dev, qp, in, pd);
+ 		err = create_raw_packet_qp(dev, qp, in, inlen, pd);
  	} else {
  		err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
  	}
@@@ -2153,6 -2143,7 +2167,6 @@@ static struct ib_qp *mlx5_ib_create_dct
  					struct ib_qp_init_attr *attr,
  					struct mlx5_ib_create_qp *ucmd)
  {
 -	struct mlx5_ib_dev *dev;
  	struct mlx5_ib_qp *qp;
  	int err = 0;
  	u32 uidx = MLX5_IB_DEFAULT_UIDX;
@@@ -2161,6 -2152,8 +2175,6 @@@
  	if (!attr->srq || !attr->recv_cq)
  		return ERR_PTR(-EINVAL);
  
 -	dev = to_mdev(pd->device);
 -
  	err = get_qp_user_index(to_mucontext(pd->uobject->context),
  				ucmd, sizeof(*ucmd), &uidx);
  	if (err)
@@@ -3116,8 -3109,10 +3130,10 @@@ static int __mlx5_ib_modify_qp(struct i
  		goto out;
  
  	if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||
- 	    !optab[mlx5_cur][mlx5_new])
+ 	    !optab[mlx5_cur][mlx5_new]) {
+ 		err = -EINVAL;
  		goto out;
+ 	}
  
  	op = optab[mlx5_cur][mlx5_new];
  	optpar = ib_mask_to_mlx5_opt(attr_mask);
diff --combined drivers/net/dsa/b53/b53_common.c
index cd16067265dd,63e02a54d537..78616787f2a3
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@@ -814,8 -814,8 +814,8 @@@ void b53_get_strings(struct dsa_switch 
  	unsigned int i;
  
  	for (i = 0; i < mib_size; i++)
- 		memcpy(data + i * ETH_GSTRING_LEN,
- 		       mibs[i].name, ETH_GSTRING_LEN);
+ 		strlcpy(data + i * ETH_GSTRING_LEN,
+ 			mibs[i].name, ETH_GSTRING_LEN);
  }
  EXPORT_SYMBOL(b53_get_strings);
  
@@@ -852,7 -852,7 +852,7 @@@ void b53_get_ethtool_stats(struct dsa_s
  }
  EXPORT_SYMBOL(b53_get_ethtool_stats);
  
 -int b53_get_sset_count(struct dsa_switch *ds)
 +int b53_get_sset_count(struct dsa_switch *ds, int port)
  {
  	struct b53_device *dev = ds->priv;
  
diff --combined drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 99c9b88d6d34,61022b5f6743..e880be8e3c45
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@@ -75,7 -75,6 +75,7 @@@
  #include "t4fw_api.h"
  #include "t4fw_version.h"
  #include "cxgb4_dcb.h"
 +#include "srq.h"
  #include "cxgb4_debugfs.h"
  #include "clip_tbl.h"
  #include "l2t.h"
@@@ -211,9 -210,6 +211,9 @@@ static void link_report(struct net_devi
  		case 40000:
  			s = "40Gbps";
  			break;
 +		case 50000:
 +			s = "50Gbps";
 +			break;
  		case 100000:
  			s = "100Gbps";
  			break;
@@@ -587,10 -583,6 +587,10 @@@ static int fwevtq_handler(struct sge_rs
  		const struct cpl_abort_rpl_rss *p = (void *)rsp;
  
  		hash_del_filter_rpl(q->adap, p);
 +	} else if (opcode == CPL_SRQ_TABLE_RPL) {
 +		const struct cpl_srq_table_rpl *p = (void *)rsp;
 +
 +		do_srq_table_rpl(q->adap, p);
  	} else
  		dev_err(q->adap->pdev_dev,
  			"unexpected CPL %#x on FW event queue\n", opcode);
@@@ -1741,11 -1733,10 +1741,11 @@@ EXPORT_SYMBOL(cxgb4_sync_txq_pidx)
  
  int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
  {
 -	struct adapter *adap;
 -	u32 offset, memtype, memaddr;
  	u32 edc0_size, edc1_size, mc0_size, mc1_size, size;
  	u32 edc0_end, edc1_end, mc0_end, mc1_end;
 +	u32 offset, memtype, memaddr;
 +	struct adapter *adap;
 +	u32 hma_size = 0;
  	int ret;
  
  	adap = netdev2adap(dev);
@@@ -1765,10 -1756,6 +1765,10 @@@
  	size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
  	mc0_size = EXT_MEM0_SIZE_G(size) << 20;
  
 +	if (t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A) & HMA_MUX_F) {
 +		size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
 +		hma_size = EXT_MEM1_SIZE_G(size) << 20;
 +	}
  	edc0_end = edc0_size;
  	edc1_end = edc0_end + edc1_size;
  	mc0_end = edc1_end + mc0_size;
@@@ -1780,10 -1767,7 +1780,10 @@@
  		memtype = MEM_EDC1;
  		memaddr = offset - edc0_end;
  	} else {
 -		if (offset < mc0_end) {
 +		if (hma_size && (offset < (edc1_end + hma_size))) {
 +			memtype = MEM_HMA;
 +			memaddr = offset - edc1_end;
 +		} else if (offset < mc0_end) {
  			memtype = MEM_MC0;
  			memaddr = offset - edc1_end;
  		} else if (is_t5(adap->params.chip)) {
@@@ -2886,11 -2870,11 +2886,11 @@@ static int cxgb_set_tx_maxrate(struct n
  	/* Convert from Mbps to Kbps */
  	req_rate = rate << 10;
  
 -	/* Max rate is 10 Gbps */
 +	/* Max rate is 100 Gbps */
  	if (req_rate >= SCHED_MAX_RATE_KBPS) {
  		dev_err(adap->pdev_dev,
 -			"Invalid rate %u Mbps, Max rate is %u Gbps\n",
 -			rate, SCHED_MAX_RATE_KBPS);
 +			"Invalid rate %u Mbps, Max rate is %u Mbps\n",
 +			rate, SCHED_MAX_RATE_KBPS >> 10);
  		return -ERANGE;
  	}
  
@@@ -3260,14 -3244,6 +3260,14 @@@ static const struct ethtool_ops cxgb4_m
  	.get_drvinfo       = cxgb4_mgmt_get_drvinfo,
  };
  
 +static void notify_fatal_err(struct work_struct *work)
 +{
 +	struct adapter *adap;
 +
 +	adap = container_of(work, struct adapter, fatal_err_notify_task);
 +	notify_ulds(adap, CXGB4_STATE_FATAL_ERROR);
 +}
 +
  void t4_fatal_err(struct adapter *adap)
  {
  	int port;
@@@ -3292,7 -3268,6 +3292,7 @@@
  		netif_carrier_off(dev);
  	}
  	dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
 +	queue_work(adap->workq, &adap->fatal_err_notify_task);
  }
  
  static void setup_memwin(struct adapter *adap)
@@@ -3323,206 -3298,6 +3323,206 @@@ static void setup_memwin_rdma(struct ad
  	}
  }
  
 +/* HMA Definitions */
 +
 +/* The maximum number of address that can be send in a single FW cmd */
 +#define HMA_MAX_ADDR_IN_CMD	5
 +
 +#define HMA_PAGE_SIZE		PAGE_SIZE
 +
 +#define HMA_MAX_NO_FW_ADDRESS	(16 << 10)  /* FW supports 16K addresses */
 +
 +#define HMA_PAGE_ORDER					\
 +	((HMA_PAGE_SIZE < HMA_MAX_NO_FW_ADDRESS) ?	\
 +	ilog2(HMA_MAX_NO_FW_ADDRESS / HMA_PAGE_SIZE) : 0)
 +
 +/* The minimum and maximum possible HMA sizes that can be specified in the FW
 + * configuration(in units of MB).
 + */
 +#define HMA_MIN_TOTAL_SIZE	1
 +#define HMA_MAX_TOTAL_SIZE				\
 +	(((HMA_PAGE_SIZE << HMA_PAGE_ORDER) *		\
 +	  HMA_MAX_NO_FW_ADDRESS) >> 20)
 +
 +static void adap_free_hma_mem(struct adapter *adapter)
 +{
 +	struct scatterlist *iter;
 +	struct page *page;
 +	int i;
 +
 +	if (!adapter->hma.sgt)
 +		return;
 +
 +	if (adapter->hma.flags & HMA_DMA_MAPPED_FLAG) {
 +		dma_unmap_sg(adapter->pdev_dev, adapter->hma.sgt->sgl,
 +			     adapter->hma.sgt->nents, PCI_DMA_BIDIRECTIONAL);
 +		adapter->hma.flags &= ~HMA_DMA_MAPPED_FLAG;
 +	}
 +
 +	for_each_sg(adapter->hma.sgt->sgl, iter,
 +		    adapter->hma.sgt->orig_nents, i) {
 +		page = sg_page(iter);
 +		if (page)
 +			__free_pages(page, HMA_PAGE_ORDER);
 +	}
 +
 +	kfree(adapter->hma.phy_addr);
 +	sg_free_table(adapter->hma.sgt);
 +	kfree(adapter->hma.sgt);
 +	adapter->hma.sgt = NULL;
 +}
 +
 +static int adap_config_hma(struct adapter *adapter)
 +{
 +	struct scatterlist *sgl, *iter;
 +	struct sg_table *sgt;
 +	struct page *newpage;
 +	unsigned int i, j, k;
 +	u32 param, hma_size;
 +	unsigned int ncmds;
 +	size_t page_size;
 +	u32 page_order;
 +	int node, ret;
 +
 +	/* HMA is supported only for T6+ cards.
 +	 * Avoid initializing HMA in kdump kernels.
 +	 */
 +	if (is_kdump_kernel() ||
 +	    CHELSIO_CHIP_VERSION(adapter->params.chip) < CHELSIO_T6)
 +		return 0;
 +
 +	/* Get the HMA region size required by fw */
 +	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
 +		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_HMA_SIZE));
 +	ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
 +			      1, &param, &hma_size);
 +	/* An error means card has its own memory or HMA is not supported by
 +	 * the firmware. Return without any errors.
 +	 */
 +	if (ret || !hma_size)
 +		return 0;
 +
 +	if (hma_size < HMA_MIN_TOTAL_SIZE ||
 +	    hma_size > HMA_MAX_TOTAL_SIZE) {
 +		dev_err(adapter->pdev_dev,
 +			"HMA size %uMB beyond bounds(%u-%lu)MB\n",
 +			hma_size, HMA_MIN_TOTAL_SIZE, HMA_MAX_TOTAL_SIZE);
 +		return -EINVAL;
 +	}
 +
 +	page_size = HMA_PAGE_SIZE;
 +	page_order = HMA_PAGE_ORDER;
 +	adapter->hma.sgt = kzalloc(sizeof(*adapter->hma.sgt), GFP_KERNEL);
 +	if (unlikely(!adapter->hma.sgt)) {
 +		dev_err(adapter->pdev_dev, "HMA SG table allocation failed\n");
 +		return -ENOMEM;
 +	}
 +	sgt = adapter->hma.sgt;
 +	/* FW returned value will be in MB's
 +	 */
 +	sgt->orig_nents = (hma_size << 20) / (page_size << page_order);
 +	if (sg_alloc_table(sgt, sgt->orig_nents, GFP_KERNEL)) {
 +		dev_err(adapter->pdev_dev, "HMA SGL allocation failed\n");
 +		kfree(adapter->hma.sgt);
 +		adapter->hma.sgt = NULL;
 +		return -ENOMEM;
 +	}
 +
 +	sgl = adapter->hma.sgt->sgl;
 +	node = dev_to_node(adapter->pdev_dev);
 +	for_each_sg(sgl, iter, sgt->orig_nents, i) {
 +		newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL,
 +					   page_order);
 +		if (!newpage) {
 +			dev_err(adapter->pdev_dev,
 +				"Not enough memory for HMA page allocation\n");
 +			ret = -ENOMEM;
 +			goto free_hma;
 +		}
 +		sg_set_page(iter, newpage, page_size << page_order, 0);
 +	}
 +
 +	sgt->nents = dma_map_sg(adapter->pdev_dev, sgl, sgt->orig_nents,
 +				DMA_BIDIRECTIONAL);
 +	if (!sgt->nents) {
 +		dev_err(adapter->pdev_dev,
 +			"Not enough memory for HMA DMA mapping");
 +		ret = -ENOMEM;
 +		goto free_hma;
 +	}
 +	adapter->hma.flags |= HMA_DMA_MAPPED_FLAG;
 +
 +	adapter->hma.phy_addr = kcalloc(sgt->nents, sizeof(dma_addr_t),
 +					GFP_KERNEL);
 +	if (unlikely(!adapter->hma.phy_addr))
 +		goto free_hma;
 +
 +	for_each_sg(sgl, iter, sgt->nents, i) {
 +		newpage = sg_page(iter);
 +		adapter->hma.phy_addr[i] = sg_dma_address(iter);
 +	}
 +
 +	ncmds = DIV_ROUND_UP(sgt->nents, HMA_MAX_ADDR_IN_CMD);
 +	/* Pass on the addresses to firmware */
 +	for (i = 0, k = 0; i < ncmds; i++, k += HMA_MAX_ADDR_IN_CMD) {
 +		struct fw_hma_cmd hma_cmd;
 +		u8 naddr = HMA_MAX_ADDR_IN_CMD;
 +		u8 soc = 0, eoc = 0;
 +		u8 hma_mode = 1; /* Presently we support only Page table mode */
 +
 +		soc = (i == 0) ? 1 : 0;
 +		eoc = (i == ncmds - 1) ? 1 : 0;
 +
 +		/* For last cmd, set naddr corresponding to remaining
 +		 * addresses
 +		 */
 +		if (i == ncmds - 1) {
 +			naddr = sgt->nents % HMA_MAX_ADDR_IN_CMD;
 +			naddr = naddr ? naddr : HMA_MAX_ADDR_IN_CMD;
 +		}
 +		memset(&hma_cmd, 0, sizeof(hma_cmd));
 +		hma_cmd.op_pkd = htonl(FW_CMD_OP_V(FW_HMA_CMD) |
 +				       FW_CMD_REQUEST_F | FW_CMD_WRITE_F);
 +		hma_cmd.retval_len16 = htonl(FW_LEN16(hma_cmd));
 +
 +		hma_cmd.mode_to_pcie_params =
 +			htonl(FW_HMA_CMD_MODE_V(hma_mode) |
 +			      FW_HMA_CMD_SOC_V(soc) | FW_HMA_CMD_EOC_V(eoc));
 +
 +		/* HMA cmd size specified in MB's */
 +		hma_cmd.naddr_size =
 +			htonl(FW_HMA_CMD_SIZE_V(hma_size) |
 +			      FW_HMA_CMD_NADDR_V(naddr));
 +
 +		/* Total Page size specified in units of 4K */
 +		hma_cmd.addr_size_pkd =
 +			htonl(FW_HMA_CMD_ADDR_SIZE_V
 +				((page_size << page_order) >> 12));
 +
 +		/* Fill the 5 addresses */
 +		for (j = 0; j < naddr; j++) {
 +			hma_cmd.phy_address[j] =
 +				cpu_to_be64(adapter->hma.phy_addr[j + k]);
 +		}
 +		ret = t4_wr_mbox(adapter, adapter->mbox, &hma_cmd,
 +				 sizeof(hma_cmd), &hma_cmd);
 +		if (ret) {
 +			dev_err(adapter->pdev_dev,
 +				"HMA FW command failed with err %d\n", ret);
 +			goto free_hma;
 +		}
 +	}
 +
 +	if (!ret)
 +		dev_info(adapter->pdev_dev,
 +			 "Reserved %uMB host memory for HMA\n", hma_size);
 +	return ret;
 +
 +free_hma:
 +	adap_free_hma_mem(adapter);
 +	return ret;
 +}
 +
  static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
  {
  	u32 v;
@@@ -3976,12 -3751,6 +3976,12 @@@ static int adap_init0_config(struct ada
  	if (ret < 0)
  		goto bye;
  
 +	/* We will proceed even if HMA init fails. */
 +	ret = adap_config_hma(adapter);
 +	if (ret)
 +		dev_err(adapter->pdev_dev,
 +			"HMA configuration failed with error %d\n", ret);
 +
  	/*
  	 * And finally tell the firmware to initialize itself using the
  	 * parameters from the Configuration File.
@@@ -4188,11 -3957,6 +4188,11 @@@ static int adap_init0(struct adapter *a
  	 * effect. Otherwise, it's time to try initializing the adapter.
  	 */
  	if (state == DEV_STATE_INIT) {
 +		ret = adap_config_hma(adap);
 +		if (ret)
 +			dev_err(adap->pdev_dev,
 +				"HMA configuration failed with error %d\n",
 +				ret);
  		dev_info(adap->pdev_dev, "Coming up as %s: "\
  			 "Adapter already initialized\n",
  			 adap->flags & MASTER_PF ? "MASTER" : "SLAVE");
@@@ -4472,20 -4236,6 +4472,20 @@@
  		adap->vres.pbl.start = val[4];
  		adap->vres.pbl.size = val[5] - val[4] + 1;
  
 +		params[0] = FW_PARAM_PFVF(SRQ_START);
 +		params[1] = FW_PARAM_PFVF(SRQ_END);
 +		ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
 +				      params, val);
 +		if (!ret) {
 +			adap->vres.srq.start = val[0];
 +			adap->vres.srq.size = val[1] - val[0] + 1;
 +		}
 +		if (adap->vres.srq.size) {
 +			adap->srq = t4_init_srq(adap->vres.srq.size);
 +			if (!adap->srq)
 +				dev_warn(&adap->pdev->dev, "could not allocate SRQ, continuing\n");
 +		}
 +
  		params[0] = FW_PARAM_PFVF(SQRQ_START);
  		params[1] = FW_PARAM_PFVF(SQRQ_END);
  		params[2] = FW_PARAM_PFVF(CQ_START);
@@@ -4519,18 -4269,6 +4519,18 @@@
  			 "max_ordird_qp %d max_ird_adapter %d\n",
  			 adap->params.max_ordird_qp,
  			 adap->params.max_ird_adapter);
 +
 +		/* Enable write_with_immediate if FW supports it */
 +		params[0] = FW_PARAM_DEV(RDMA_WRITE_WITH_IMM);
 +		ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, params,
 +				      val);
 +		adap->params.write_w_imm_support = (ret == 0 && val[0] != 0);
 +
 +		/* Enable write_cmpl if FW supports it */
 +		params[0] = FW_PARAM_DEV(RI_WRITE_CMPL_WR);
 +		ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, params,
 +				      val);
 +		adap->params.write_cmpl_support = (ret == 0 && val[0] != 0);
  		adap->num_ofld_uld += 2;
  	}
  	if (caps_cmd.iscsicaps) {
@@@ -4608,7 -4346,6 +4608,7 @@@
  	 * happened to HW/FW, stop issuing commands.
  	 */
  bye:
 +	adap_free_hma_mem(adap);
  	kfree(adap->sge.egr_map);
  	kfree(adap->sge.ingr_map);
  	kfree(adap->sge.starving_fl);
@@@ -5166,7 -4903,6 +5166,7 @@@ static void free_some_resources(struct 
  
  	kvfree(adapter->smt);
  	kvfree(adapter->l2t);
 +	kvfree(adapter->srq);
  	t4_cleanup_sched(adapter);
  	kvfree(adapter->tids.tid_tab);
  	cxgb4_cleanup_tc_flower(adapter);
@@@ -5234,7 -4970,6 +5234,6 @@@ static void cxgb4_mgmt_setup(struct net
  	/* Initialize the device structure. */
  	dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
  	dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
- 	dev->needs_free_netdev = true;
  }
  
  static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
@@@ -5445,6 -5180,8 +5444,8 @@@ static int init_one(struct pci_dev *pde
  	adapter->name = pci_name(pdev);
  	adapter->mbox = func;
  	adapter->pf = func;
+ 	adapter->params.chip = chip;
+ 	adapter->adap_idx = adap_idx;
  	adapter->msg_enable = DFLT_MSG_ENABLE;
  	adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) +
  				    (sizeof(struct mbox_cmd) *
@@@ -5520,7 -5257,6 +5521,7 @@@
  	INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
  	INIT_WORK(&adapter->db_full_task, process_db_full);
  	INIT_WORK(&adapter->db_drop_task, process_db_drop);
 +	INIT_WORK(&adapter->fatal_err_notify_task, notify_fatal_err);
  
  	err = t4_prep_adapter(adapter);
  	if (err)
@@@ -5838,8 -5574,6 +5839,8 @@@ static void remove_one(struct pci_dev *
  			t4_uld_clean_up(adapter);
  		}
  
 +		adap_free_hma_mem(adapter);
 +
  		disable_interrupts(adapter);
  
  		for_each_port(adapter, i)
diff --combined drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 159dc2df878d,e4ec32a9ca15..fd43f98ddbe7
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@@ -454,16 -454,6 +454,16 @@@ static void dpaa_set_rx_mode(struct net
  				  err);
  	}
  
 +	if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) {
 +		priv->mac_dev->allmulti = !priv->mac_dev->allmulti;
 +		err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac,
 +						  priv->mac_dev->allmulti);
 +		if (err < 0)
 +			netif_err(priv, drv, net_dev,
 +				  "mac_dev->set_allmulti() = %d\n",
 +				  err);
 +	}
 +
  	err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
  	if (err < 0)
  		netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
@@@ -1926,10 -1916,8 +1926,10 @@@ static int skb_to_sg_fd(struct dpaa_pri
  		goto csum_failed;
  	}
  
 +	/* SGT[0] is used by the linear part */
  	sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
 -	qm_sg_entry_set_len(&sgt[0], skb_headlen(skb));
 +	frag_len = skb_headlen(skb);
 +	qm_sg_entry_set_len(&sgt[0], frag_len);
  	sgt[0].bpid = FSL_DPAA_BPID_INV;
  	sgt[0].offset = 0;
  	addr = dma_map_single(dev, skb->data,
@@@ -1942,9 -1930,9 +1942,9 @@@
  	qm_sg_entry_set64(&sgt[0], addr);
  
  	/* populate the rest of SGT entries */
 -	frag = &skb_shinfo(skb)->frags[0];
 -	frag_len = frag->size;
 -	for (i = 1; i <= nr_frags; i++, frag++) {
 +	for (i = 0; i < nr_frags; i++) {
 +		frag = &skb_shinfo(skb)->frags[i];
 +		frag_len = frag->size;
  		WARN_ON(!skb_frag_page(frag));
  		addr = skb_frag_dma_map(dev, frag, 0,
  					frag_len, dma_dir);
@@@ -1954,16 -1942,15 +1954,16 @@@
  			goto sg_map_failed;
  		}
  
 -		qm_sg_entry_set_len(&sgt[i], frag_len);
 -		sgt[i].bpid = FSL_DPAA_BPID_INV;
 -		sgt[i].offset = 0;
 +		qm_sg_entry_set_len(&sgt[i + 1], frag_len);
 +		sgt[i + 1].bpid = FSL_DPAA_BPID_INV;
 +		sgt[i + 1].offset = 0;
  
  		/* keep the offset in the address */
 -		qm_sg_entry_set64(&sgt[i], addr);
 -		frag_len = frag->size;
 +		qm_sg_entry_set64(&sgt[i + 1], addr);
  	}
 -	qm_sg_entry_set_f(&sgt[i - 1], frag_len);
 +
 +	/* Set the final bit in the last used entry of the SGT */
 +	qm_sg_entry_set_f(&sgt[nr_frags], frag_len);
  
  	qm_fd_set_sg(fd, priv->tx_headroom, skb->len);
  
@@@ -2021,7 -2008,6 +2021,6 @@@ static inline int dpaa_xmit(struct dpaa
  	}
  
  	if (unlikely(err < 0)) {
- 		percpu_stats->tx_errors++;
  		percpu_stats->tx_fifo_errors++;
  		return err;
  	}
@@@ -2065,23 -2051,19 +2064,23 @@@ static int dpaa_start_xmit(struct sk_bu
  	/* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES;
  	 * make sure we don't feed FMan with more fragments than it supports.
  	 */
 -	if (nonlinear &&
 -	    likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) {
 -		/* Just create a S/G fd based on the skb */
 -		err = skb_to_sg_fd(priv, skb, &fd);
 -		percpu_priv->tx_frag_skbuffs++;
 -	} else {
 +	if (unlikely(nonlinear &&
 +		     (skb_shinfo(skb)->nr_frags >= DPAA_SGT_MAX_ENTRIES))) {
  		/* If the egress skb contains more fragments than we support
  		 * we have no choice but to linearize it ourselves.
  		 */
 -		if (unlikely(nonlinear) && __skb_linearize(skb))
 +		if (__skb_linearize(skb))
  			goto enomem;
  
 -		/* Finally, create a contig FD from this skb */
 +		nonlinear = skb_is_nonlinear(skb);
 +	}
 +
 +	if (nonlinear) {
 +		/* Just create a S/G fd based on the skb */
 +		err = skb_to_sg_fd(priv, skb, &fd);
 +		percpu_priv->tx_frag_skbuffs++;
 +	} else {
 +		/* Create a contig FD from this skb */
  		err = skb_to_contig_fd(priv, skb, &fd, &offset);
  	}
  	if (unlikely(err < 0))
@@@ -2218,8 -2200,14 +2217,8 @@@ static enum qman_cb_dqrr_result rx_erro
  	if (dpaa_eth_napi_schedule(percpu_priv, portal))
  		return qman_cb_dqrr_stop;
  
 -	if (dpaa_eth_refill_bpools(priv))
 -		/* Unable to refill the buffer pool due to insufficient
 -		 * system memory. Just release the frame back into the pool,
 -		 * otherwise we'll soon end up with an empty buffer pool.
 -		 */
 -		dpaa_fd_release(net_dev, &dq->fd);
 -	else
 -		dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
 +	dpaa_eth_refill_bpools(priv);
 +	dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
  
  	return qman_cb_dqrr_consume;
  }
@@@ -2289,7 -2277,6 +2288,6 @@@ static enum qman_cb_dqrr_result rx_defa
  	vaddr = phys_to_virt(addr);
  	prefetch(vaddr + qm_fd_get_offset(fd));
  
- 	fd_format = qm_fd_get_format(fd);
  	/* The only FD types that we may receive are contig and S/G */
  	WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
  
@@@ -2322,8 -2309,10 +2320,10 @@@
  
  	skb_len = skb->len;
  
- 	if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
+ 	if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) {
+ 		percpu_stats->rx_dropped++;
  		return qman_cb_dqrr_consume;
+ 	}
  
  	percpu_stats->rx_packets++;
  	percpu_stats->rx_bytes += skb_len;
@@@ -2777,7 -2766,7 +2777,7 @@@ static int dpaa_eth_probe(struct platfo
  
  	priv->channel = (u16)channel;
  
 -	/* Start a thread that will walk the CPUs with affine portals
 +	/* Walk the CPUs with affine portals
  	 * and add this pool channel to each's dequeue mask.
  	 */
  	dpaa_eth_add_channel(priv->channel);
@@@ -2871,7 -2860,7 +2871,7 @@@ static int dpaa_remove(struct platform_
  	struct device *dev;
  	int err;
  
- 	dev = &pdev->dev;
+ 	dev = pdev->dev.parent;
  	net_dev = dev_get_drvdata(dev);
  
  	priv = netdev_priv(net_dev);
diff --combined drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 9a581faaa742,7af31ddd093f..57b1e2b47c0a
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@@ -1100,7 -1100,7 +1100,7 @@@ int dtsec_add_hash_mac_address(struct f
  	set_bucket(dtsec->regs, bucket, true);
  
  	/* Create element to be added to the driver hash table */
- 	hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+ 	hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
  	if (!hash_entry)
  		return -ENOMEM;
  	hash_entry->addr = addr;
@@@ -1117,25 -1117,6 +1117,25 @@@
  	return 0;
  }
  
 +int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
 +{
 +	u32 tmp;
 +	struct dtsec_regs __iomem *regs = dtsec->regs;
 +
 +	if (!is_init_done(dtsec->dtsec_drv_param))
 +		return -EINVAL;
 +
 +	tmp = ioread32be(&regs->rctrl);
 +	if (enable)
 +		tmp |= RCTRL_MPROM;
 +	else
 +		tmp &= ~RCTRL_MPROM;
 +
 +	iowrite32be(tmp, &regs->rctrl);
 +
 +	return 0;
 +}
 +
  int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
  {
  	struct dtsec_regs __iomem *regs = dtsec->regs;
diff --combined drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
index ba338428ffd1,996dc099cd58..3c0d882ba183
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
 - * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
 + * Copyright (c) 2017, 2018 Mellanox Technologies. All rights reserved.
   * Copyright (c) 2017 Jiri Pirko <jiri at mellanox.com>
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -443,6 -443,17 +443,17 @@@ int mlxsw_afa_block_jump(struct mlxsw_a
  }
  EXPORT_SYMBOL(mlxsw_afa_block_jump);
  
+ int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block)
+ {
+ 	if (block->finished)
+ 		return -EINVAL;
+ 	mlxsw_afa_set_goto_set(block->cur_set,
+ 			       MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0);
+ 	block->finished = true;
+ 	return 0;
+ }
+ EXPORT_SYMBOL(mlxsw_afa_block_terminate);
+ 
  static struct mlxsw_afa_fwd_entry *
  mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u8 local_port)
  {
@@@ -838,6 -849,7 +849,6 @@@ struct mlxsw_afa_mirror 
  	struct mlxsw_afa_resource resource;
  	int span_id;
  	u8 local_in_port;
 -	u8 local_out_port;
  	bool ingress;
  };
  
@@@ -847,7 -859,7 +858,7 @@@ mlxsw_afa_mirror_destroy(struct mlxsw_a
  {
  	block->afa->ops->mirror_del(block->afa->ops_priv,
  				    mirror->local_in_port,
 -				    mirror->local_out_port,
 +				    mirror->span_id,
  				    mirror->ingress);
  	kfree(mirror);
  }
@@@ -863,8 -875,9 +874,8 @@@ mlxsw_afa_mirror_destructor(struct mlxs
  }
  
  static struct mlxsw_afa_mirror *
 -mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
 -			u8 local_in_port, u8 local_out_port,
 -			bool ingress)
 +mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, u8 local_in_port,
 +			const struct net_device *out_dev, bool ingress)
  {
  	struct mlxsw_afa_mirror *mirror;
  	int err;
@@@ -874,12 -887,13 +885,12 @@@
  		return ERR_PTR(-ENOMEM);
  
  	err = block->afa->ops->mirror_add(block->afa->ops_priv,
 -					  local_in_port, local_out_port,
 +					  local_in_port, out_dev,
  					  ingress, &mirror->span_id);
  	if (err)
  		goto err_mirror_add;
  
  	mirror->ingress = ingress;
 -	mirror->local_out_port = local_out_port;
  	mirror->local_in_port = local_in_port;
  	mirror->resource.destructor = mlxsw_afa_mirror_destructor;
  	mlxsw_afa_resource_add(block, &mirror->resource);
@@@ -906,13 -920,13 +917,13 @@@ mlxsw_afa_block_append_allocated_mirror
  }
  
  int
 -mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
 -			      u8 local_in_port, u8 local_out_port, bool ingress)
 +mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, u8 local_in_port,
 +			      const struct net_device *out_dev, bool ingress)
  {
  	struct mlxsw_afa_mirror *mirror;
  	int err;
  
 -	mirror = mlxsw_afa_mirror_create(block, local_in_port, local_out_port,
 +	mirror = mlxsw_afa_mirror_create(block, local_in_port, out_dev,
  					 ingress);
  	if (IS_ERR(mirror))
  		return PTR_ERR(mirror);
diff --combined drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
index 6dd601703c99,b91f2b0829b0..3a155d104384
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
@@@ -36,7 -36,6 +36,7 @@@
  #define _MLXSW_CORE_ACL_FLEX_ACTIONS_H
  
  #include <linux/types.h>
 +#include <linux/netdevice.h>
  
  struct mlxsw_afa;
  struct mlxsw_afa_block;
@@@ -49,10 -48,9 +49,10 @@@ struct mlxsw_afa_ops 
  	void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index);
  	int (*counter_index_get)(void *priv, unsigned int *p_counter_index);
  	void (*counter_index_put)(void *priv, unsigned int counter_index);
 -	int (*mirror_add)(void *priv, u8 locol_in_port, u8 local_out_port,
 +	int (*mirror_add)(void *priv, u8 local_in_port,
 +			  const struct net_device *out_dev,
  			  bool ingress, int *p_span_id);
 -	void (*mirror_del)(void *priv, u8 locol_in_port, u8 local_out_port,
 +	void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
  			   bool ingress);
  };
  
@@@ -67,13 -65,13 +67,14 @@@ char *mlxsw_afa_block_first_set(struct 
  u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block);
  int mlxsw_afa_block_continue(struct mlxsw_afa_block *block);
  int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id);
+ int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block);
  int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block);
  int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
  int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
  					    u16 trap_id);
  int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
 -				  u8 local_in_port, u8 local_out_port,
 +				  u8 local_in_port,
 +				  const struct net_device *out_dev,
  				  bool ingress);
  int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
  			       u8 local_port, bool in_port);
diff --combined drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 92194a9b2caf,92064db2ae44..21bee8f19894
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@@ -70,23 -70,16 +70,23 @@@
  #define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR "linear"
  #define MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE "hash_single"
  #define MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE "hash_double"
 +#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES "singles"
 +#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS "chunks"
 +#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"
  
  enum mlxsw_sp_resource_id {
  	MLXSW_SP_RESOURCE_KVD,
  	MLXSW_SP_RESOURCE_KVD_LINEAR,
  	MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
  	MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
 +	MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
 +	MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
 +	MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
  };
  
  struct mlxsw_sp_port;
  struct mlxsw_sp_rif;
 +struct mlxsw_sp_span_entry;
  
  struct mlxsw_sp_upper {
  	struct net_device *dev;
@@@ -118,13 -111,35 +118,13 @@@ struct mlxsw_sp_mid 
  	unsigned long *ports_in_mid; /* bits array */
  };
  
 -enum mlxsw_sp_span_type {
 -	MLXSW_SP_SPAN_EGRESS,
 -	MLXSW_SP_SPAN_INGRESS
 -};
 -
 -struct mlxsw_sp_span_inspected_port {
 -	struct list_head list;
 -	enum mlxsw_sp_span_type type;
 -	u8 local_port;
 -
 -	/* Whether this is a directly bound mirror (port-to-port) or an ACL. */
 -	bool bound;
 -};
 -
 -struct mlxsw_sp_span_entry {
 -	u8 local_port;
 -	bool used;
 -	struct list_head bound_ports_list;
 -	int ref_count;
 -	int id;
 -};
 -
  enum mlxsw_sp_port_mall_action_type {
  	MLXSW_SP_PORT_MALL_MIRROR,
  	MLXSW_SP_PORT_MALL_SAMPLE,
  };
  
  struct mlxsw_sp_port_mall_mirror_tc_entry {
 -	u8 to_local_port;
 +	int span_id;
  	bool ingress;
  };
  
@@@ -211,8 -226,6 +211,8 @@@ struct mlxsw_sp_port_xstats 
  	u64 wred_drop[TC_MAX_QUEUE];
  	u64 tail_drop[TC_MAX_QUEUE];
  	u64 backlog[TC_MAX_QUEUE];
 +	u64 tx_bytes[IEEE_8021QAZ_MAX_TCS];
 +	u64 tx_packets[IEEE_8021QAZ_MAX_TCS];
  };
  
  struct mlxsw_sp_port {
@@@ -250,7 -263,6 +250,7 @@@
  	struct mlxsw_sp_port_sample *sample;
  	struct list_head vlans_list;
  	struct mlxsw_sp_qdisc *root_qdisc;
 +	struct mlxsw_sp_qdisc *tclass_qdiscs;
  	unsigned acl_rule_count;
  	struct mlxsw_sp_acl_block *ing_acl_block;
  	struct mlxsw_sp_acl_block *eg_acl_block;
@@@ -388,6 -400,16 +388,6 @@@ struct mlxsw_sp_port *mlxsw_sp_port_dev
  struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
  void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
  struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
 -int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
 -			     struct mlxsw_sp_port *to,
 -			     enum mlxsw_sp_span_type type,
 -			     bool bind);
 -void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from,
 -			      u8 destination_port,
 -			      enum mlxsw_sp_span_type type,
 -			      bool bind);
 -struct mlxsw_sp_span_entry *
 -mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port);
  
  /* spectrum_dcb.c */
  #ifdef CONFIG_MLXSW_SPECTRUM_DCB
@@@ -443,7 -465,6 +443,7 @@@ int mlxsw_sp_kvdl_alloc_size_query(stru
  				   unsigned int entry_count,
  				   unsigned int *p_alloc_size);
  u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp);
 +int mlxsw_sp_kvdl_resources_register(struct devlink *devlink);
  
  struct mlxsw_sp_acl_rule_info {
  	unsigned int priority;
@@@ -535,6 -556,7 +535,7 @@@ void mlxsw_sp_acl_rulei_keymask_buf(str
  int mlxsw_sp_acl_rulei_act_continue(struct mlxsw_sp_acl_rule_info *rulei);
  int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei,
  				u16 group_id);
+ int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei);
  int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei);
  int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei);
  int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp,
diff --combined drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index 1c1601a43978,92d90ed7207e..79b1fa27a9a4
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@@ -160,13 -160,6 +160,13 @@@ bool mlxsw_sp_acl_block_disabled(struc
  	return block->disable_count;
  }
  
 +static bool
 +mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
 +{
 +	/* We hold a reference on ruleset ourselves */
 +	return ruleset->ref_count == 2;
 +}
 +
  static int
  mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
  			  struct mlxsw_sp_acl_block *block,
@@@ -348,8 -341,21 +348,8 @@@ mlxsw_sp_acl_ruleset_create(struct mlxs
  	if (err)
  		goto err_ht_insert;
  
 -	if (!chain_index) {
 -		/* We only need ruleset with chain index 0, the implicit one,
 -		 * to be directly bound to device. The rest of the rulesets
 -		 * are bound by "Goto action set".
 -		 */
 -		err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset, block);
 -		if (err)
 -			goto err_ruleset_bind;
 -	}
 -
  	return ruleset;
  
 -err_ruleset_bind:
 -	rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
 -			       mlxsw_sp_acl_ruleset_ht_params);
  err_ht_insert:
  	ops->ruleset_del(mlxsw_sp, ruleset->priv);
  err_ops_ruleset_add:
@@@ -363,8 -369,12 +363,8 @@@ static void mlxsw_sp_acl_ruleset_destro
  					 struct mlxsw_sp_acl_ruleset *ruleset)
  {
  	const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
 -	struct mlxsw_sp_acl_block *block = ruleset->ht_key.block;
 -	u32 chain_index = ruleset->ht_key.chain_index;
  	struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
  
 -	if (!chain_index)
 -		mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset, block);
  	rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
  			       mlxsw_sp_acl_ruleset_ht_params);
  	ops->ruleset_del(mlxsw_sp, ruleset->priv);
@@@ -518,6 -528,11 +518,11 @@@ int mlxsw_sp_acl_rulei_act_jump(struct 
  	return mlxsw_afa_block_jump(rulei->act_block, group_id);
  }
  
+ int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei)
+ {
+ 	return mlxsw_afa_block_terminate(rulei->act_block);
+ }
+ 
  int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei)
  {
  	return mlxsw_afa_block_append_drop(rulei->act_block);
@@@ -562,6 -577,7 +567,6 @@@ int mlxsw_sp_acl_rulei_act_mirror(struc
  				  struct net_device *out_dev)
  {
  	struct mlxsw_sp_acl_block_binding *binding;
 -	struct mlxsw_sp_port *out_port;
  	struct mlxsw_sp_port *in_port;
  
  	if (!list_is_singular(&block->binding_list))
@@@ -570,10 -586,16 +575,10 @@@
  	binding = list_first_entry(&block->binding_list,
  				   struct mlxsw_sp_acl_block_binding, list);
  	in_port = binding->mlxsw_sp_port;
 -	if (!mlxsw_sp_port_dev_check(out_dev))
 -		return -EINVAL;
 -
 -	out_port = netdev_priv(out_dev);
 -	if (out_port->mlxsw_sp != mlxsw_sp)
 -		return -EINVAL;
  
  	return mlxsw_afa_block_append_mirror(rulei->act_block,
  					     in_port->local_port,
 -					     out_port->local_port,
 +					     out_dev,
  					     binding->ingress);
  }
  
@@@ -678,25 -700,10 +683,25 @@@ int mlxsw_sp_acl_rule_add(struct mlxsw_
  	if (err)
  		goto err_rhashtable_insert;
  
 +	if (!ruleset->ht_key.chain_index &&
 +	    mlxsw_sp_acl_ruleset_is_singular(ruleset)) {
 +		/* We only need ruleset with chain index 0, the implicit
 +		 * one, to be directly bound to device. The rest of the
 +		 * rulesets are bound by "Goto action set".
 +		 */
 +		err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset,
 +						      ruleset->ht_key.block);
 +		if (err)
 +			goto err_ruleset_block_bind;
 +	}
 +
  	list_add_tail(&rule->list, &mlxsw_sp->acl->rules);
  	ruleset->ht_key.block->rule_count++;
  	return 0;
  
 +err_ruleset_block_bind:
 +	rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
 +			       mlxsw_sp_acl_rule_ht_params);
  err_rhashtable_insert:
  	ops->rule_del(mlxsw_sp, rule->priv);
  	return err;
@@@ -710,10 -717,6 +715,10 @@@ void mlxsw_sp_acl_rule_del(struct mlxsw
  
  	ruleset->ht_key.block->rule_count--;
  	list_del(&rule->list);
 +	if (!ruleset->ht_key.chain_index &&
 +	    mlxsw_sp_acl_ruleset_is_singular(ruleset))
 +		mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset,
 +						  ruleset->ht_key.block);
  	rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
  			       mlxsw_sp_acl_rule_ht_params);
  	ops->rule_del(mlxsw_sp, rule->priv);
diff --combined drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
index 948aceb512c5,000000000000..4b87ec20e658
mode 100644,000000..100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@@ -1,104 -1,0 +1,107 @@@
 +/*
 + * drivers/net/ethernet/mellanox/mlxsw/mlxsw_span.h
 + * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions are met:
 + *
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. Neither the names of the copyright holders nor the names of its
 + *    contributors may be used to endorse or promote products derived from
 + *    this software without specific prior written permission.
 + *
 + * Alternatively, this software may be distributed under the terms of the
 + * GNU General Public License ("GPL") version 2 as published by the Free
 + * Software Foundation.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#ifndef _MLXSW_SPECTRUM_SPAN_H
 +#define _MLXSW_SPECTRUM_SPAN_H
 +
 +#include <linux/types.h>
 +#include <linux/if_ether.h>
 +
 +#include "spectrum_router.h"
 +
 +struct mlxsw_sp;
 +struct mlxsw_sp_port;
 +
 +enum mlxsw_sp_span_type {
 +	MLXSW_SP_SPAN_EGRESS,
 +	MLXSW_SP_SPAN_INGRESS
 +};
 +
 +struct mlxsw_sp_span_inspected_port {
 +	struct list_head list;
 +	enum mlxsw_sp_span_type type;
 +	u8 local_port;
++
++	/* Whether this is a directly bound mirror (port-to-port) or an ACL. */
++	bool bound;
 +};
 +
 +struct mlxsw_sp_span_parms {
 +	struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */
 +	unsigned int ttl;
 +	unsigned char dmac[ETH_ALEN];
 +	unsigned char smac[ETH_ALEN];
 +	union mlxsw_sp_l3addr daddr;
 +	union mlxsw_sp_l3addr saddr;
 +};
 +
 +struct mlxsw_sp_span_entry_ops;
 +
 +struct mlxsw_sp_span_entry {
 +	const struct net_device *to_dev;
 +	const struct mlxsw_sp_span_entry_ops *ops;
 +	struct mlxsw_sp_span_parms parms;
 +	struct list_head bound_ports_list;
 +	int ref_count;
 +	int id;
 +};
 +
 +struct mlxsw_sp_span_entry_ops {
 +	bool (*can_handle)(const struct net_device *to_dev);
 +	int (*parms)(const struct net_device *to_dev,
 +		     struct mlxsw_sp_span_parms *sparmsp);
 +	int (*configure)(struct mlxsw_sp_span_entry *span_entry,
 +			 struct mlxsw_sp_span_parms sparms);
 +	void (*deconfigure)(struct mlxsw_sp_span_entry *span_entry);
 +};
 +
 +int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp);
 +void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
 +void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
 +
 +int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
 +			     const struct net_device *to_dev,
 +			     enum mlxsw_sp_span_type type,
 +			     bool bind, int *p_span_id);
 +void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
 +			      enum mlxsw_sp_span_type type, bool bind);
 +struct mlxsw_sp_span_entry *
 +mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
 +				 const struct net_device *to_dev);
 +
 +void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
 +				    struct mlxsw_sp_span_entry *span_entry);
 +
 +int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
 +
 +#endif
diff --combined drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 03ad4eeac7f8,d5d02be72947..69051e98aff9
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@@ -1703,6 -1703,13 +1703,13 @@@ qed_iwarp_parse_rx_pkt(struct qed_hwfn 
  	iph = (struct iphdr *)((u8 *)(ethh) + eth_hlen);
  
  	if (eth_type == ETH_P_IP) {
+ 		if (iph->protocol != IPPROTO_TCP) {
+ 			DP_NOTICE(p_hwfn,
+ 				  "Unexpected ip protocol on ll2 %x\n",
+ 				  iph->protocol);
+ 			return -EINVAL;
+ 		}
+ 
  		cm_info->local_ip[0] = ntohl(iph->daddr);
  		cm_info->remote_ip[0] = ntohl(iph->saddr);
  		cm_info->ip_version = TCP_IPV4;
@@@ -1711,6 -1718,14 +1718,14 @@@
  		*payload_len = ntohs(iph->tot_len) - ip_hlen;
  	} else if (eth_type == ETH_P_IPV6) {
  		ip6h = (struct ipv6hdr *)iph;
+ 
+ 		if (ip6h->nexthdr != IPPROTO_TCP) {
+ 			DP_NOTICE(p_hwfn,
+ 				  "Unexpected ip protocol on ll2 %x\n",
+ 				  iph->protocol);
+ 			return -EINVAL;
+ 		}
+ 
  		for (i = 0; i < 4; i++) {
  			cm_info->local_ip[i] =
  			    ntohl(ip6h->daddr.in6_u.u6_addr32[i]);
@@@ -1784,7 -1799,7 +1799,7 @@@ enum qed_iwarp_mpa_pkt_type 
  /* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */
  #define QED_IWARP_MAX_BDS_PER_FPDU 3
  
 -char *pkt_type_str[] = {
 +static const char * const pkt_type_str[] = {
  	"QED_IWARP_MPA_PKT_PACKED",
  	"QED_IWARP_MPA_PKT_PARTIAL",
  	"QED_IWARP_MPA_PKT_UNALIGNED"
@@@ -1928,8 -1943,8 +1943,8 @@@ qed_iwarp_update_fpdu_length(struct qed
  		/* Missing lower byte is now available */
  		mpa_len = fpdu->fpdu_length | *mpa_data;
  		fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len);
- 		fpdu->mpa_frag_len = fpdu->fpdu_length;
  		/* one byte of hdr */
+ 		fpdu->mpa_frag_len = 1;
  		fpdu->incomplete_bytes = fpdu->fpdu_length - 1;
  		DP_VERBOSE(p_hwfn,
  			   QED_MSG_RDMA,
diff --combined drivers/net/ethernet/ti/cpsw.c
index 8af8891078e2,b2b30c9df037..1b4af54a4968
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@@ -120,18 -120,14 +120,18 @@@ do {								
  #define CPDMA_RXCP		0x60
  
  #define CPSW_POLL_WEIGHT	64
 +#define CPSW_RX_VLAN_ENCAP_HDR_SIZE		4
  #define CPSW_MIN_PACKET_SIZE	(VLAN_ETH_ZLEN)
 -#define CPSW_MAX_PACKET_SIZE	(VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
 +#define CPSW_MAX_PACKET_SIZE	(VLAN_ETH_FRAME_LEN +\
 +				 ETH_FCS_LEN +\
 +				 CPSW_RX_VLAN_ENCAP_HDR_SIZE)
  
  #define RX_PRIORITY_MAPPING	0x76543210
  #define TX_PRIORITY_MAPPING	0x33221100
  #define CPDMA_TX_PRIORITY_MAP	0x01234567
  
  #define CPSW_VLAN_AWARE		BIT(1)
 +#define CPSW_RX_VLAN_ENCAP	BIT(2)
  #define CPSW_ALE_VLAN_AWARE	1
  
  #define CPSW_FIFO_NORMAL_MODE		(0 << 16)
@@@ -152,18 -148,6 +152,18 @@@
  #define CPSW_MAX_QUEUES		8
  #define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256
  
 +#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT	29
 +#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK		GENMASK(2, 0)
 +#define CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT	16
 +#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT	8
 +#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK	GENMASK(1, 0)
 +enum {
 +	CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG = 0,
 +	CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV,
 +	CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG,
 +	CPSW_RX_VLAN_ENCAP_HDR_PKT_UNTAG,
 +};
 +
  static int debug_level;
  module_param(debug_level, int, 0);
  MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@@ -734,49 -718,6 +734,49 @@@ static void cpsw_tx_handler(void *token
  	dev_kfree_skb_any(skb);
  }
  
 +static void cpsw_rx_vlan_encap(struct sk_buff *skb)
 +{
 +	struct cpsw_priv *priv = netdev_priv(skb->dev);
 +	struct cpsw_common *cpsw = priv->cpsw;
 +	u32 rx_vlan_encap_hdr = *((u32 *)skb->data);
 +	u16 vtag, vid, prio, pkt_type;
 +
 +	/* Remove VLAN header encapsulation word */
 +	skb_pull(skb, CPSW_RX_VLAN_ENCAP_HDR_SIZE);
 +
 +	pkt_type = (rx_vlan_encap_hdr >>
 +		    CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT) &
 +		    CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK;
 +	/* Ignore unknown & Priority-tagged packets*/
 +	if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV ||
 +	    pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG)
 +		return;
 +
 +	vid = (rx_vlan_encap_hdr >>
 +	       CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT) &
 +	       VLAN_VID_MASK;
 +	/* Ignore vid 0 and pass packet as is */
 +	if (!vid)
 +		return;
 +	/* Ignore default vlans in dual mac mode */
 +	if (cpsw->data.dual_emac &&
 +	    vid == cpsw->slaves[priv->emac_port].port_vlan)
 +		return;
 +
 +	prio = (rx_vlan_encap_hdr >>
 +		CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT) &
 +		CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK;
 +
 +	vtag = (prio << VLAN_PRIO_SHIFT) | vid;
 +	__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vtag);
 +
 +	/* strip vlan tag for VLAN-tagged packet */
 +	if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG) {
 +		memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
 +		skb_pull(skb, VLAN_HLEN);
 +	}
 +}
 +
  static void cpsw_rx_handler(void *token, int len, int status)
  {
  	struct cpdma_chan	*ch;
@@@ -811,8 -752,6 +811,8 @@@
  	if (new_skb) {
  		skb_copy_queue_mapping(new_skb, skb);
  		skb_put(skb, len);
 +		if (status & CPDMA_RX_VLAN_ENCAP)
 +			cpsw_rx_vlan_encap(skb);
  		cpts_rx_timestamp(cpsw->cpts, skb);
  		skb->protocol = eth_type_trans(skb, ndev);
  		netif_receive_skb(skb);
@@@ -1075,7 -1014,8 +1075,8 @@@ static void _cpsw_adjust_link(struct cp
  		/* set speed_in input in case RMII mode is used in 100Mbps */
  		if (phy->speed == 100)
  			mac_control |= BIT(15);
- 		else if (phy->speed == 10)
+ 		/* in band mode only works in 10Mbps RGMII mode */
+ 		else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
  			mac_control |= BIT(18); /* In Band mode */
  
  		if (priv->rx_pause)
@@@ -1467,7 -1407,7 +1468,7 @@@ static void cpsw_init_host_port(struct 
  	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
  			     CPSW_ALE_VLAN_AWARE);
  	control_reg = readl(&cpsw->regs->control);
 -	control_reg |= CPSW_VLAN_AWARE;
 +	control_reg |= CPSW_VLAN_AWARE | CPSW_RX_VLAN_ENCAP;
  	writel(control_reg, &cpsw->regs->control);
  	fifo_mode = (cpsw->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE :
  		     CPSW_FIFO_NORMAL_MODE;
@@@ -3183,7 -3123,7 +3184,7 @@@ static int cpsw_probe(struct platform_d
  			cpsw->quirk_irq = true;
  	}
  
 -	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 +	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
  
  	ndev->netdev_ops = &cpsw_netdev_ops;
  	ndev->ethtool_ops = &cpsw_ethtool_ops;
diff --combined drivers/net/hyperv/netvsc.c
index aa95e81af6e5,7472172823f3..4123d081b1c7
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@@ -36,7 -36,6 +36,7 @@@
  #include <asm/sync_bitops.h>
  
  #include "hyperv_net.h"
 +#include "netvsc_trace.h"
  
  /*
   * Switch the data path from the synthetic interface to the VF
@@@ -58,8 -57,6 +58,8 @@@ void netvsc_switch_datapath(struct net_
  		init_pkt->msg.v4_msg.active_dp.active_datapath =
  			NVSP_DATAPATH_SYNTHETIC;
  
 +	trace_nvsp_send(ndev, init_pkt);
 +
  	vmbus_sendpacket(dev->channel, init_pkt,
  			       sizeof(struct nvsp_message),
  			       (unsigned long)init_pkt,
@@@ -93,6 -90,11 +93,11 @@@ static void free_netvsc_device(struct r
  		= container_of(head, struct netvsc_device, rcu);
  	int i;
  
+ 	kfree(nvdev->extension);
+ 	vfree(nvdev->recv_buf);
+ 	vfree(nvdev->send_buf);
+ 	kfree(nvdev->send_section_map);
+ 
  	for (i = 0; i < VRSS_CHANNEL_MAX; i++)
  		vfree(nvdev->chan_table[i].mrc.slots);
  
@@@ -127,8 -129,6 +132,8 @@@ static void netvsc_revoke_buf(struct hv
  		revoke_packet->msg.v1_msg.
  		revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
  
 +		trace_nvsp_send(ndev, revoke_packet);
 +
  		ret = vmbus_sendpacket(device->channel,
  				       revoke_packet,
  				       sizeof(struct nvsp_message),
@@@ -169,8 -169,6 +174,8 @@@
  		revoke_packet->msg.v1_msg.revoke_send_buf.id =
  			NETVSC_SEND_BUFFER_ID;
  
 +		trace_nvsp_send(ndev, revoke_packet);
 +
  		ret = vmbus_sendpacket(device->channel,
  				       revoke_packet,
  				       sizeof(struct nvsp_message),
@@@ -218,12 -216,6 +223,6 @@@ static void netvsc_teardown_gpadl(struc
  		net_device->recv_buf_gpadl_handle = 0;
  	}
  
- 	if (net_device->recv_buf) {
- 		/* Free up the receive buffer */
- 		vfree(net_device->recv_buf);
- 		net_device->recv_buf = NULL;
- 	}
- 
  	if (net_device->send_buf_gpadl_handle) {
  		ret = vmbus_teardown_gpadl(device->channel,
  					   net_device->send_buf_gpadl_handle);
@@@ -238,12 -230,6 +237,6 @@@
  		}
  		net_device->send_buf_gpadl_handle = 0;
  	}
- 	if (net_device->send_buf) {
- 		/* Free up the send buffer */
- 		vfree(net_device->send_buf);
- 		net_device->send_buf = NULL;
- 	}
- 	kfree(net_device->send_section_map);
  }
  
  int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx)
@@@ -312,8 -298,6 +305,8 @@@ static int netvsc_init_buf(struct hv_de
  	init_packet->msg.v1_msg.
  		send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
  
 +	trace_nvsp_send(ndev, init_packet);
 +
  	/* Send the gpadl notification request */
  	ret = vmbus_sendpacket(device->channel, init_packet,
  			       sizeof(struct nvsp_message),
@@@ -393,8 -377,6 +386,8 @@@
  		net_device->send_buf_gpadl_handle;
  	init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID;
  
 +	trace_nvsp_send(ndev, init_packet);
 +
  	/* Send the gpadl notification request */
  	ret = vmbus_sendpacket(device->channel, init_packet,
  			       sizeof(struct nvsp_message),
@@@ -463,8 -445,6 +456,8 @@@ static int negotiate_nvsp_ver(struct hv
  	init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver;
  	init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver;
  
 +	trace_nvsp_send(ndev, init_packet);
 +
  	/* Send the init request */
  	ret = vmbus_sendpacket(device->channel, init_packet,
  			       sizeof(struct nvsp_message),
@@@ -497,8 -477,6 +490,8 @@@
  		init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1;
  	}
  
 +	trace_nvsp_send(ndev, init_packet);
 +
  	ret = vmbus_sendpacket(device->channel, init_packet,
  				sizeof(struct nvsp_message),
  				(unsigned long)init_packet,
@@@ -511,7 -489,6 +504,7 @@@ static int netvsc_connect_vsp(struct hv
  			      struct netvsc_device *net_device,
  			      const struct netvsc_device_info *device_info)
  {
 +	struct net_device *ndev = hv_get_drvdata(device);
  	static const u32 ver_list[] = {
  		NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
  		NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5
@@@ -552,8 -529,6 +545,8 @@@
  		send_ndis_ver.ndis_minor_ver =
  				ndis_version & 0xFFFF;
  
 +	trace_nvsp_send(ndev, init_packet);
 +
  	/* Send the init request */
  	ret = vmbus_sendpacket(device->channel, init_packet,
  				sizeof(struct nvsp_message),
@@@ -580,26 -555,29 +573,29 @@@ void netvsc_device_remove(struct hv_dev
  		= rtnl_dereference(net_device_ctx->nvdev);
  	int i;
  
- 	cancel_work_sync(&net_device->subchan_work);
- 
  	netvsc_revoke_buf(device, net_device);
  
  	RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
  
+ 	/* And disassociate NAPI context from device */
+ 	for (i = 0; i < net_device->num_chn; i++)
+ 		netif_napi_del(&net_device->chan_table[i].napi);
+ 
  	/*
  	 * At this point, no one should be accessing net_device
  	 * except in here
  	 */
  	netdev_dbg(ndev, "net device safe to remove\n");
  
+ 	/* older versions require that buffer be revoked before close */
+ 	if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_4)
+ 		netvsc_teardown_gpadl(device, net_device);
+ 
  	/* Now, we can close the channel safely */
  	vmbus_close(device->channel);
  
- 	netvsc_teardown_gpadl(device, net_device);
- 
- 	/* And dissassociate NAPI context from device */
- 	for (i = 0; i < net_device->num_chn; i++)
- 		netif_napi_del(&net_device->chan_table[i].napi);
+ 	if (net_device->nvsp_version >= NVSP_PROTOCOL_VERSION_4)
+ 		netvsc_teardown_gpadl(device, net_device);
  
  	/* Release all resources */
  	free_netvsc_device_rcu(net_device);
@@@ -663,14 -641,18 +659,18 @@@ static void netvsc_send_tx_complete(str
  	queue_sends =
  		atomic_dec_return(&net_device->chan_table[q_idx].queue_sends);
  
- 	if (net_device->destroy && queue_sends == 0)
- 		wake_up(&net_device->wait_drain);
- 
- 	if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
- 	    (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
- 	     queue_sends < 1)) {
- 		netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
- 		ndev_ctx->eth_stats.wake_queue++;
+ 	if (unlikely(net_device->destroy)) {
+ 		if (queue_sends == 0)
+ 			wake_up(&net_device->wait_drain);
+ 	} else {
+ 		struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx);
+ 
+ 		if (netif_tx_queue_stopped(txq) &&
+ 		    (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
+ 		     queue_sends < 1)) {
+ 			netif_tx_wake_queue(txq);
+ 			ndev_ctx->eth_stats.wake_queue++;
+ 		}
  	}
  }
  
@@@ -765,7 -747,7 +765,7 @@@ static inline int netvsc_send_pkt
  	struct sk_buff *skb)
  {
  	struct nvsp_message nvmsg;
 -	struct nvsp_1_message_send_rndis_packet * const rpkt =
 +	struct nvsp_1_message_send_rndis_packet *rpkt =
  		&nvmsg.msg.v1_msg.send_rndis_pkt;
  	struct netvsc_channel * const nvchan =
  		&net_device->chan_table[packet->q_idx];
@@@ -794,8 -776,6 +794,8 @@@
  	if (out_channel->rescind)
  		return -ENODEV;
  
 +	trace_nvsp_send_pkt(ndev, out_channel, rpkt);
 +
  	if (packet->page_buf_cnt) {
  		if (packet->cp_partial)
  			pb += packet->rmsg_pgcnt;
@@@ -1099,8 -1079,6 +1099,8 @@@ static int netvsc_receive(struct net_de
  			+ vmxferpage_packet->ranges[i].byte_offset;
  		u32 buflen = vmxferpage_packet->ranges[i].byte_count;
  
 +		trace_rndis_recv(ndev, q_idx, data);
 +
  		/* Pass it to the upper layer */
  		status = rndis_filter_receive(ndev, net_device,
  					      channel, data, buflen);
@@@ -1165,8 -1143,6 +1165,8 @@@ static int netvsc_process_raw_pkt(struc
  	struct net_device_context *net_device_ctx = netdev_priv(ndev);
  	struct nvsp_message *nvmsg = hv_pkt_data(desc);
  
 +	trace_nvsp_recv(ndev, channel, nvmsg);
 +
  	switch (desc->type) {
  	case VM_PKT_COMP:
  		netvsc_send_completion(net_device, channel, device,
diff --combined drivers/net/hyperv/rndis_filter.c
index 2dc00f714482,a6ec41c399d6..020f8bc54386
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@@ -31,7 -31,6 +31,7 @@@
  #include <linux/rtnetlink.h>
  
  #include "hyperv_net.h"
 +#include "netvsc_trace.h"
  
  static void rndis_set_multicast(struct work_struct *w);
  
@@@ -242,8 -241,6 +242,8 @@@ static int rndis_filter_send_request(st
  			pb[0].len;
  	}
  
 +	trace_rndis_send(dev->ndev, 0, &req->request_msg);
 +
  	rcu_read_lock_bh();
  	ret = netvsc_send(dev->ndev, packet, NULL, pb, NULL);
  	rcu_read_unlock_bh();
@@@ -267,13 -264,23 +267,23 @@@ static void rndis_set_link_state(struc
  	}
  }
  
- static void rndis_filter_receive_response(struct rndis_device *dev,
- 				       struct rndis_message *resp)
+ static void rndis_filter_receive_response(struct net_device *ndev,
+ 					  struct netvsc_device *nvdev,
+ 					  const struct rndis_message *resp)
  {
+ 	struct rndis_device *dev = nvdev->extension;
  	struct rndis_request *request = NULL;
  	bool found = false;
  	unsigned long flags;
- 	struct net_device *ndev = dev->ndev;
+ 
+ 	/* This should never happen, it means control message
+ 	 * response received after device removed.
+ 	 */
+ 	if (dev->state == RNDIS_DEV_UNINITIALIZED) {
+ 		netdev_err(ndev,
+ 			   "got rndis message uninitialized\n");
+ 		return;
+ 	}
  
  	spin_lock_irqsave(&dev->request_lock, flags);
  	list_for_each_entry(request, &dev->req_list, list_ent) {
@@@ -355,7 -362,6 +365,6 @@@ static inline void *rndis_get_ppi(struc
  
  static int rndis_filter_receive_data(struct net_device *ndev,
  				     struct netvsc_device *nvdev,
- 				     struct rndis_device *dev,
  				     struct rndis_message *msg,
  				     struct vmbus_channel *channel,
  				     void *data, u32 data_buflen)
@@@ -375,7 -381,7 +384,7 @@@
  	 * should be the data packet size plus the trailer padding size
  	 */
  	if (unlikely(data_buflen < rndis_pkt->data_len)) {
- 		netdev_err(dev->ndev, "rndis message buffer "
+ 		netdev_err(ndev, "rndis message buffer "
  			   "overflow detected (got %u, min %u)"
  			   "...dropping this message!\n",
  			   data_buflen, rndis_pkt->data_len);
@@@ -403,35 -409,20 +412,20 @@@ int rndis_filter_receive(struct net_dev
  			 void *data, u32 buflen)
  {
  	struct net_device_context *net_device_ctx = netdev_priv(ndev);
- 	struct rndis_device *rndis_dev = net_dev->extension;
  	struct rndis_message *rndis_msg = data;
  
- 	/* Make sure the rndis device state is initialized */
- 	if (unlikely(!rndis_dev)) {
- 		netif_dbg(net_device_ctx, rx_err, ndev,
- 			  "got rndis message but no rndis device!\n");
- 		return NVSP_STAT_FAIL;
- 	}
- 
- 	if (unlikely(rndis_dev->state == RNDIS_DEV_UNINITIALIZED)) {
- 		netif_dbg(net_device_ctx, rx_err, ndev,
- 			  "got rndis message uninitialized\n");
- 		return NVSP_STAT_FAIL;
- 	}
- 
  	if (netif_msg_rx_status(net_device_ctx))
  		dump_rndis_message(ndev, rndis_msg);
  
  	switch (rndis_msg->ndis_msg_type) {
  	case RNDIS_MSG_PACKET:
- 		return rndis_filter_receive_data(ndev, net_dev,
- 						 rndis_dev, rndis_msg,
+ 		return rndis_filter_receive_data(ndev, net_dev, rndis_msg,
  						 channel, data, buflen);
  	case RNDIS_MSG_INIT_C:
  	case RNDIS_MSG_QUERY_C:
  	case RNDIS_MSG_SET_C:
  		/* completion msgs */
- 		rndis_filter_receive_response(rndis_dev, rndis_msg);
+ 		rndis_filter_receive_response(ndev, net_dev, rndis_msg);
  		break;
  
  	case RNDIS_MSG_INDICATE:
@@@ -828,13 -819,15 +822,15 @@@ static int rndis_filter_set_packet_filt
  	struct rndis_set_request *set;
  	int ret;
  
+ 	if (dev->filter == new_filter)
+ 		return 0;
+ 
  	request = get_rndis_request(dev, RNDIS_MSG_SET,
  			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
  			sizeof(u32));
  	if (!request)
  		return -ENOMEM;
  
- 
  	/* Setup the rndis set */
  	set = &request->request_msg.msg.set_req;
  	set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
@@@ -845,8 -838,10 +841,10 @@@
  	       &new_filter, sizeof(u32));
  
  	ret = rndis_filter_send_request(dev, request);
- 	if (ret == 0)
+ 	if (ret == 0) {
  		wait_for_completion(&request->wait_event);
+ 		dev->filter = new_filter;
+ 	}
  
  	put_rndis_request(dev, request);
  
@@@ -864,9 -859,9 +862,9 @@@ static void rndis_set_multicast(struct 
  		filter = NDIS_PACKET_TYPE_PROMISCUOUS;
  	} else {
  		if (flags & IFF_ALLMULTI)
- 			flags |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+ 			filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
  		if (flags & IFF_BROADCAST)
- 			flags |= NDIS_PACKET_TYPE_BROADCAST;
+ 			filter |= NDIS_PACKET_TYPE_BROADCAST;
  	}
  
  	rndis_filter_set_packet_filter(rdev, filter);
@@@ -947,11 -942,12 +945,11 @@@ static bool netvsc_device_idle(const st
  	return true;
  }
  
 -static void rndis_filter_halt_device(struct rndis_device *dev)
 +static void rndis_filter_halt_device(struct netvsc_device *nvdev,
 +				     struct rndis_device *dev)
  {
  	struct rndis_request *request;
  	struct rndis_halt_request *halt;
 -	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
 -	struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
  
  	/* Attempt to do a rndis device halt */
  	request = get_rndis_request(dev, RNDIS_MSG_HALT,
@@@ -1090,8 -1086,6 +1088,8 @@@ void rndis_set_subchannel(struct work_s
  	init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
  	init_packet->msg.v5_msg.subchn_req.num_subchannels =
  						nvdev->num_chn - 1;
 +	trace_nvsp_send(ndev, init_packet);
 +
  	ret = vmbus_sendpacket(hv_dev->channel, init_packet,
  			       sizeof(struct nvsp_message),
  			       (unsigned long)init_packet,
@@@ -1124,6 -1118,7 +1122,7 @@@
  	for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
  		ndev_ctx->tx_table[i] = i % nvdev->num_chn;
  
+ 	netif_device_attach(ndev);
  	rtnl_unlock();
  	return;
  
@@@ -1134,6 -1129,8 +1133,8 @@@ failed
  
  	nvdev->max_chn = 1;
  	nvdev->num_chn = 1;
+ 
+ 	netif_device_attach(ndev);
  unlock:
  	rtnl_unlock();
  }
@@@ -1336,6 -1333,10 +1337,10 @@@ out
  		net_device->num_chn = 1;
  	}
  
+ 	/* No sub channels, device is ready */
+ 	if (net_device->num_chn == 1)
+ 		netif_device_attach(net);
+ 
  	return net_device;
  
  err_dev_remv:
@@@ -1348,16 -1349,12 +1353,12 @@@ void rndis_filter_device_remove(struct 
  {
  	struct rndis_device *rndis_dev = net_dev->extension;
  
- 	/* Don't try and setup sub channels if about to halt */
- 	cancel_work_sync(&net_dev->subchan_work);
- 
  	/* Halt and release the rndis device */
 -	rndis_filter_halt_device(rndis_dev);
 +	rndis_filter_halt_device(net_dev, rndis_dev);
  
  	net_dev->extension = NULL;
  
  	netvsc_device_remove(dev);
- 	kfree(rndis_dev);
  }
  
  int rndis_filter_open(struct netvsc_device *nvdev)
@@@ -1375,10 -1372,3 +1376,3 @@@ int rndis_filter_close(struct netvsc_de
  
  	return rndis_filter_close_device(nvdev->extension);
  }
- 
- bool rndis_filter_opened(const struct netvsc_device *nvdev)
- {
- 	const struct rndis_device *dev = nvdev->extension;
- 
- 	return dev->state == RNDIS_DEV_DATAINITIALIZED;
- }
diff --combined drivers/net/phy/marvell.c
index 98fd6b7ceeec,0e0978d8a0eb..a75c511950c3
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@@ -860,7 -860,7 +860,7 @@@ static int m88e1510_config_init(struct 
  			return err;
  
  		/* There appears to be a bug in the 88e1512 when used in
 -		 * SGMII to copper mode, where the AN advertisment register
 +		 * SGMII to copper mode, where the AN advertisement register
  		 * clears the pause bits each time a negotiation occurs.
  		 * This means we can never be truely sure what was advertised,
  		 * so disable Pause support.
@@@ -1452,8 -1452,8 +1452,8 @@@ static void marvell_get_strings(struct 
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
- 		memcpy(data + i * ETH_GSTRING_LEN,
- 		       marvell_hw_stats[i].string, ETH_GSTRING_LEN);
+ 		strlcpy(data + i * ETH_GSTRING_LEN,
+ 			marvell_hw_stats[i].string, ETH_GSTRING_LEN);
  	}
  }
  
diff --combined drivers/net/phy/phy.c
index c2d9027be863,9aabfa1a455a..05c1e8ef15e6
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@@ -618,6 -618,77 +618,68 @@@ static void phy_error(struct phy_devic
  }
  
  /**
+  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
+  * @phydev: target phy_device struct
+  */
+ static int phy_disable_interrupts(struct phy_device *phydev)
+ {
+ 	int err;
+ 
+ 	/* Disable PHY interrupts */
+ 	err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
+ 	if (err)
 -		goto phy_err;
++		return err;
+ 
+ 	/* Clear the interrupt */
 -	err = phy_clear_interrupt(phydev);
 -	if (err)
 -		goto phy_err;
 -
 -	return 0;
 -
 -phy_err:
 -	phy_error(phydev);
 -
 -	return err;
++	return phy_clear_interrupt(phydev);
+ }
+ 
+ /**
+  * phy_change - Called by the phy_interrupt to handle PHY changes
+  * @phydev: phy_device struct that interrupted
+  */
+ static irqreturn_t phy_change(struct phy_device *phydev)
+ {
+ 	if (phy_interrupt_is_valid(phydev)) {
+ 		if (phydev->drv->did_interrupt &&
+ 		    !phydev->drv->did_interrupt(phydev))
+ 			return IRQ_NONE;
+ 
+ 		if (phydev->state == PHY_HALTED)
+ 			if (phy_disable_interrupts(phydev))
+ 				goto phy_err;
+ 	}
+ 
+ 	mutex_lock(&phydev->lock);
+ 	if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
+ 		phydev->state = PHY_CHANGELINK;
+ 	mutex_unlock(&phydev->lock);
+ 
+ 	/* reschedule state queue work to run as soon as possible */
+ 	phy_trigger_machine(phydev, true);
+ 
+ 	if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev))
+ 		goto phy_err;
+ 	return IRQ_HANDLED;
+ 
+ phy_err:
+ 	phy_error(phydev);
+ 	return IRQ_NONE;
+ }
+ 
+ /**
+  * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
+  * @work: work_struct that describes the work to be done
+  */
+ void phy_change_work(struct work_struct *work)
+ {
+ 	struct phy_device *phydev =
+ 		container_of(work, struct phy_device, phy_queue);
+ 
+ 	phy_change(phydev);
+ }
+ 
+ /**
   * phy_interrupt - PHY interrupt handler
   * @irq: interrupt line
   * @phy_dat: phy_device pointer
@@@ -632,9 -703,7 +694,7 @@@ static irqreturn_t phy_interrupt(int ir
  	if (PHY_HALTED == phydev->state)
  		return IRQ_NONE;		/* It can't be ours.  */
  
- 	phy_change(phydev);
- 
- 	return IRQ_HANDLED;
+ 	return phy_change(phydev);
  }
  
  /**
@@@ -652,23 -721,6 +712,6 @@@ static int phy_enable_interrupts(struc
  }
  
  /**
-  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
-  * @phydev: target phy_device struct
-  */
- static int phy_disable_interrupts(struct phy_device *phydev)
- {
- 	int err;
- 
- 	/* Disable PHY interrupts */
- 	err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
- 	if (err)
- 		return err;
- 
- 	/* Clear the interrupt */
- 	return phy_clear_interrupt(phydev);
- }
- 
- /**
   * phy_start_interrupts - request and enable interrupts for a PHY device
   * @phydev: target phy_device struct
   *
@@@ -711,50 -763,6 +754,6 @@@ int phy_stop_interrupts(struct phy_devi
  EXPORT_SYMBOL(phy_stop_interrupts);
  
  /**
-  * phy_change - Called by the phy_interrupt to handle PHY changes
-  * @phydev: phy_device struct that interrupted
-  */
- void phy_change(struct phy_device *phydev)
- {
- 	if (phy_interrupt_is_valid(phydev)) {
- 		if (phydev->drv->did_interrupt &&
- 		    !phydev->drv->did_interrupt(phydev))
- 			return;
- 
- 		if (phydev->state == PHY_HALTED)
- 			if (phy_disable_interrupts(phydev))
- 				goto phy_err;
- 	}
- 
- 	mutex_lock(&phydev->lock);
- 	if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
- 		phydev->state = PHY_CHANGELINK;
- 	mutex_unlock(&phydev->lock);
- 
- 	/* reschedule state queue work to run as soon as possible */
- 	phy_trigger_machine(phydev, true);
- 
- 	if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev))
- 		goto phy_err;
- 	return;
- 
- phy_err:
- 	phy_error(phydev);
- }
- 
- /**
-  * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
-  * @work: work_struct that describes the work to be done
-  */
- void phy_change_work(struct work_struct *work)
- {
- 	struct phy_device *phydev =
- 		container_of(work, struct phy_device, phy_queue);
- 
- 	phy_change(phydev);
- }
- 
- /**
   * phy_stop - Bring down the PHY link, and stop checking the status
   * @phydev: target phy_device struct
   */
@@@ -765,8 -773,13 +764,8 @@@ void phy_stop(struct phy_device *phydev
  	if (PHY_HALTED == phydev->state)
  		goto out_unlock;
  
 -	if (phy_interrupt_is_valid(phydev)) {
 -		/* Disable PHY Interrupts */
 -		phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
 -
 -		/* Clear any pending interrupts */
 -		phy_clear_interrupt(phydev);
 -	}
 +	if (phy_interrupt_is_valid(phydev))
 +		phy_disable_interrupts(phydev);
  
  	phydev->state = PHY_HALTED;
  
diff --combined drivers/net/phy/phy_device.c
index b285323327c4,74664a6c0cdc..ac23322a32e1
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@@ -374,7 -374,7 +374,7 @@@ struct phy_device *phy_device_create(st
  	dev->duplex = -1;
  	dev->pause = 0;
  	dev->asym_pause = 0;
 -	dev->link = 1;
 +	dev->link = 0;
  	dev->interface = PHY_INTERFACE_MODE_GMII;
  
  	dev->autoneg = AUTONEG_ENABLE;
@@@ -1012,10 -1012,17 +1012,17 @@@ int phy_attach_direct(struct net_devic
  	err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
  				"attached_dev");
  	if (!err) {
- 		err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
- 					"phydev");
- 		if (err)
- 			goto error;
+ 		err = sysfs_create_link_nowarn(&dev->dev.kobj,
+ 					       &phydev->mdio.dev.kobj,
+ 					       "phydev");
+ 		if (err) {
+ 			dev_err(&dev->dev, "could not add device link to %s err %d\n",
+ 				kobject_name(&phydev->mdio.dev.kobj),
+ 				err);
+ 			/* non-fatal - some net drivers can use one netdevice
+ 			 * with more then one phy
+ 			 */
+ 		}
  
  		phydev->sysfs_links = true;
  	}
@@@ -1666,6 -1673,23 +1673,23 @@@ int genphy_config_init(struct phy_devic
  }
  EXPORT_SYMBOL(genphy_config_init);
  
+ /* This is used for the phy device which doesn't support the MMD extended
+  * register access, but it does have side effect when we are trying to access
+  * the MMD register via indirect method.
+  */
+ int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum)
+ {
+ 	return -EOPNOTSUPP;
+ }
+ EXPORT_SYMBOL(genphy_read_mmd_unsupported);
+ 
+ int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
+ 				 u16 regnum, u16 val)
+ {
+ 	return -EOPNOTSUPP;
+ }
+ EXPORT_SYMBOL(genphy_write_mmd_unsupported);
+ 
  int genphy_suspend(struct phy_device *phydev)
  {
  	return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
diff --combined drivers/net/ppp/ppp_generic.c
index 7dc2f34e7229,da1937832c99..926c2c322d43
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@@ -257,7 -257,7 +257,7 @@@ struct ppp_net 
  /* Prototypes. */
  static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
  			struct file *file, unsigned int cmd, unsigned long arg);
- static void ppp_xmit_process(struct ppp *ppp);
+ static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
  static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
  static void ppp_push(struct ppp *ppp);
  static void ppp_channel_push(struct channel *pch);
@@@ -513,13 -513,12 +513,12 @@@ static ssize_t ppp_write(struct file *f
  		goto out;
  	}
  
- 	skb_queue_tail(&pf->xq, skb);
- 
  	switch (pf->kind) {
  	case INTERFACE:
- 		ppp_xmit_process(PF_TO_PPP(pf));
+ 		ppp_xmit_process(PF_TO_PPP(pf), skb);
  		break;
  	case CHANNEL:
+ 		skb_queue_tail(&pf->xq, skb);
  		ppp_channel_push(PF_TO_CHANNEL(pf));
  		break;
  	}
@@@ -971,7 -970,6 +970,7 @@@ static struct pernet_operations ppp_net
  	.exit = ppp_exit_net,
  	.id   = &ppp_net_id,
  	.size = sizeof(struct ppp_net),
 +	.async = true,
  };
  
  static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set)
@@@ -1268,8 -1266,8 +1267,8 @@@ ppp_start_xmit(struct sk_buff *skb, str
  	put_unaligned_be16(proto, pp);
  
  	skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev)));
- 	skb_queue_tail(&ppp->file.xq, skb);
- 	ppp_xmit_process(ppp);
+ 	ppp_xmit_process(ppp, skb);
+ 
  	return NETDEV_TX_OK;
  
   outf:
@@@ -1421,13 -1419,14 +1420,14 @@@ static void ppp_setup(struct net_devic
   */
  
  /* Called to do any work queued up on the transmit side that can now be done */
- static void __ppp_xmit_process(struct ppp *ppp)
+ static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
  {
- 	struct sk_buff *skb;
- 
  	ppp_xmit_lock(ppp);
  	if (!ppp->closing) {
  		ppp_push(ppp);
+ 
+ 		if (skb)
+ 			skb_queue_tail(&ppp->file.xq, skb);
  		while (!ppp->xmit_pending &&
  		       (skb = skb_dequeue(&ppp->file.xq)))
  			ppp_send_frame(ppp, skb);
@@@ -1441,7 -1440,7 +1441,7 @@@
  	ppp_xmit_unlock(ppp);
  }
  
- static void ppp_xmit_process(struct ppp *ppp)
+ static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
  {
  	local_bh_disable();
  
@@@ -1449,7 -1448,7 +1449,7 @@@
  		goto err;
  
  	(*this_cpu_ptr(ppp->xmit_recursion))++;
- 	__ppp_xmit_process(ppp);
+ 	__ppp_xmit_process(ppp, skb);
  	(*this_cpu_ptr(ppp->xmit_recursion))--;
  
  	local_bh_enable();
@@@ -1459,6 -1458,8 +1459,8 @@@
  err:
  	local_bh_enable();
  
+ 	kfree_skb(skb);
+ 
  	if (net_ratelimit())
  		netdev_err(ppp->dev, "recursion detected\n");
  }
@@@ -1943,7 -1944,7 +1945,7 @@@ static void __ppp_channel_push(struct c
  	if (skb_queue_empty(&pch->file.xq)) {
  		ppp = pch->ppp;
  		if (ppp)
- 			__ppp_xmit_process(ppp);
+ 			__ppp_xmit_process(ppp, NULL);
  	}
  }
  
diff --combined drivers/net/team/team.c
index 5dd781e65958,56c701b73c12..222093e878a8
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@@ -1105,15 -1105,14 +1105,15 @@@ static void team_port_disable_netpoll(s
  }
  #endif
  
 -static int team_upper_dev_link(struct team *team, struct team_port *port)
 +static int team_upper_dev_link(struct team *team, struct team_port *port,
 +			       struct netlink_ext_ack *extack)
  {
  	struct netdev_lag_upper_info lag_upper_info;
  	int err;
  
  	lag_upper_info.tx_type = team->mode->lag_tx_type;
  	err = netdev_master_upper_dev_link(port->dev, team->dev, NULL,
 -					   &lag_upper_info, NULL);
 +					   &lag_upper_info, extack);
  	if (err)
  		return err;
  	port->dev->priv_flags |= IFF_TEAM_PORT;
@@@ -1130,8 -1129,7 +1130,8 @@@ static void __team_port_change_port_add
  static int team_dev_type_check_change(struct net_device *dev,
  				      struct net_device *port_dev);
  
 -static int team_port_add(struct team *team, struct net_device *port_dev)
 +static int team_port_add(struct team *team, struct net_device *port_dev,
 +			 struct netlink_ext_ack *extack)
  {
  	struct net_device *dev = team->dev;
  	struct team_port *port;
@@@ -1139,14 -1137,12 +1139,14 @@@
  	int err;
  
  	if (port_dev->flags & IFF_LOOPBACK) {
 +		NL_SET_ERR_MSG(extack, "Loopback device can't be added as a team port");
  		netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n",
  			   portname);
  		return -EINVAL;
  	}
  
  	if (team_port_exists(port_dev)) {
 +		NL_SET_ERR_MSG(extack, "Device is already a port of a team device");
  		netdev_err(dev, "Device %s is already a port "
  				"of a team device\n", portname);
  		return -EBUSY;
@@@ -1154,7 -1150,6 +1154,7 @@@
  
  	if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
  	    vlan_uses_dev(dev)) {
 +		NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");
  		netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n",
  			   portname);
  		return -EPERM;
@@@ -1165,7 -1160,6 +1165,7 @@@
  		return err;
  
  	if (port_dev->flags & IFF_UP) {
 +		NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port");
  		netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
  			   portname);
  		return -EBUSY;
@@@ -1233,7 -1227,7 +1233,7 @@@
  		goto err_handler_register;
  	}
  
 -	err = team_upper_dev_link(team, port);
 +	err = team_upper_dev_link(team, port, extack);
  	if (err) {
  		netdev_err(dev, "Device %s failed to set upper link\n",
  			   portname);
@@@ -1927,7 -1921,7 +1927,7 @@@ static int team_add_slave(struct net_de
  	int err;
  
  	mutex_lock(&team->lock);
 -	err = team_port_add(team, port_dev);
 +	err = team_port_add(team, port_dev, extack);
  	mutex_unlock(&team->lock);
  
  	if (!err)
@@@ -2401,7 -2395,7 +2401,7 @@@ send_done
  	if (!nlh) {
  		err = __send_and_alloc_skb(&skb, team, portid, send_func);
  		if (err)
- 			goto errout;
+ 			return err;
  		goto send_done;
  	}
  
@@@ -2687,7 -2681,7 +2687,7 @@@ send_done
  	if (!nlh) {
  		err = __send_and_alloc_skb(&skb, team, portid, send_func);
  		if (err)
- 			goto errout;
+ 			return err;
  		goto send_done;
  	}
  
diff --combined drivers/net/tun.c
index baeafa004463,28cfa642e39a..a1ba262f40ad
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@@ -78,7 -78,6 +78,7 @@@
  #include <linux/mutex.h>
  
  #include <linux/uaccess.h>
 +#include <linux/proc_fs.h>
  
  /* Uncomment to enable debugging */
  /* #define TUN_DEBUG 1 */
@@@ -656,7 -655,7 +656,7 @@@ static struct tun_struct *tun_enable_qu
  	return tun;
  }
  
- static void tun_ptr_free(void *ptr)
+ void tun_ptr_free(void *ptr)
  {
  	if (!ptr)
  		return;
@@@ -668,6 -667,7 +668,7 @@@
  		__skb_array_destroy_skb(ptr);
  	}
  }
+ EXPORT_SYMBOL_GPL(tun_ptr_free);
  
  static void tun_queue_purge(struct tun_file *tfile)
  {
@@@ -1613,6 -1613,7 +1614,6 @@@ static struct sk_buff *tun_build_skb(st
  	unsigned int delta = 0;
  	char *buf;
  	size_t copied;
 -	bool xdp_xmit = false;
  	int err, pad = TUN_RX_PAD;
  
  	rcu_read_lock();
@@@ -1670,14 -1671,8 +1671,14 @@@
  			preempt_enable();
  			return NULL;
  		case XDP_TX:
 -			xdp_xmit = true;
 -			/* fall through */
 +			get_page(alloc_frag->page);
 +			alloc_frag->offset += buflen;
 +			if (tun_xdp_xmit(tun->dev, &xdp))
 +				goto err_redirect;
 +			tun_xdp_flush(tun->dev);
 +			rcu_read_unlock();
 +			preempt_enable();
 +			return NULL;
  		case XDP_PASS:
  			delta = orig_data - xdp.data;
  			break;
@@@ -1704,6 -1699,14 +1705,6 @@@
  	get_page(alloc_frag->page);
  	alloc_frag->offset += buflen;
  
 -	if (xdp_xmit) {
 -		skb->dev = tun->dev;
 -		generic_xdp_tx(skb, xdp_prog);
 -		rcu_read_unlock();
 -		preempt_enable();
 -		return NULL;
 -	}
 -
  	rcu_read_unlock();
  	preempt_enable();
  
@@@ -2284,67 -2287,11 +2285,67 @@@ static int tun_validate(struct nlattr *
  	return -EINVAL;
  }
  
 +static size_t tun_get_size(const struct net_device *dev)
 +{
 +	BUILD_BUG_ON(sizeof(u32) != sizeof(uid_t));
 +	BUILD_BUG_ON(sizeof(u32) != sizeof(gid_t));
 +
 +	return nla_total_size(sizeof(uid_t)) + /* OWNER */
 +	       nla_total_size(sizeof(gid_t)) + /* GROUP */
 +	       nla_total_size(sizeof(u8)) + /* TYPE */
 +	       nla_total_size(sizeof(u8)) + /* PI */
 +	       nla_total_size(sizeof(u8)) + /* VNET_HDR */
 +	       nla_total_size(sizeof(u8)) + /* PERSIST */
 +	       nla_total_size(sizeof(u8)) + /* MULTI_QUEUE */
 +	       nla_total_size(sizeof(u32)) + /* NUM_QUEUES */
 +	       nla_total_size(sizeof(u32)) + /* NUM_DISABLED_QUEUES */
 +	       0;
 +}
 +
 +static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev)
 +{
 +	struct tun_struct *tun = netdev_priv(dev);
 +
 +	if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK))
 +		goto nla_put_failure;
 +	if (uid_valid(tun->owner) &&
 +	    nla_put_u32(skb, IFLA_TUN_OWNER,
 +			from_kuid_munged(current_user_ns(), tun->owner)))
 +		goto nla_put_failure;
 +	if (gid_valid(tun->group) &&
 +	    nla_put_u32(skb, IFLA_TUN_GROUP,
 +			from_kgid_munged(current_user_ns(), tun->group)))
 +		goto nla_put_failure;
 +	if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI)))
 +		goto nla_put_failure;
 +	if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR)))
 +		goto nla_put_failure;
 +	if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST)))
 +		goto nla_put_failure;
 +	if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE,
 +		       !!(tun->flags & IFF_MULTI_QUEUE)))
 +		goto nla_put_failure;
 +	if (tun->flags & IFF_MULTI_QUEUE) {
 +		if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues))
 +			goto nla_put_failure;
 +		if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES,
 +				tun->numdisabled))
 +			goto nla_put_failure;
 +	}
 +
 +	return 0;
 +
 +nla_put_failure:
 +	return -EMSGSIZE;
 +}
 +
  static struct rtnl_link_ops tun_link_ops __read_mostly = {
  	.kind		= DRV_NAME,
  	.priv_size	= sizeof(struct tun_struct),
  	.setup		= tun_setup,
  	.validate	= tun_validate,
 +	.get_size       = tun_get_size,
 +	.fill_info      = tun_fill_info,
  };
  
  static void tun_sock_write_space(struct sock *sk)
@@@ -2836,7 -2783,6 +2837,7 @@@ static long __tun_chr_ioctl(struct fil
  	struct tun_struct *tun;
  	void __user* argp = (void __user*)arg;
  	struct ifreq ifr;
 +	struct net *net;
  	kuid_t owner;
  	kgid_t group;
  	int sndbuf;
@@@ -2845,8 -2791,7 +2846,8 @@@
  	int le;
  	int ret;
  
 -	if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == SOCK_IOC_TYPE) {
 +	if (cmd == TUNSETIFF || cmd == TUNSETQUEUE ||
 +	    (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) {
  		if (copy_from_user(&ifr, argp, ifreq_len))
  			return -EFAULT;
  	} else {
@@@ -2866,7 -2811,6 +2867,7 @@@
  	rtnl_lock();
  
  	tun = tun_get(tfile);
 +	net = sock_net(&tfile->sk);
  	if (cmd == TUNSETIFF) {
  		ret = -EEXIST;
  		if (tun)
@@@ -2874,7 -2818,7 +2875,7 @@@
  
  		ifr.ifr_name[IFNAMSIZ-1] = '\0';
  
 -		ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr);
 +		ret = tun_set_iff(net, file, &ifr);
  
  		if (ret)
  			goto unlock;
@@@ -2896,14 -2840,6 +2897,14 @@@
  		tfile->ifindex = ifindex;
  		goto unlock;
  	}
 +	if (cmd == SIOCGSKNS) {
 +		ret = -EPERM;
 +		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 +			goto unlock;
 +
 +		ret = open_related_ns(&net->ns, get_net_ns);
 +		goto unlock;
 +	}
  
  	ret = -EBADFD;
  	if (!tun)
diff --combined drivers/net/wireless/mac80211_hwsim.c
index 7b6c3640a94f,35b21f8152bb..100cf42db65d
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@@ -253,7 -253,7 +253,7 @@@ static inline void hwsim_clear_chanctx_
  
  static unsigned int hwsim_net_id;
  
 -static int hwsim_netgroup;
 +static struct ida hwsim_netgroup_ida = IDA_INIT;
  
  struct hwsim_net {
  	int netgroup;
@@@ -267,13 -267,11 +267,13 @@@ static inline int hwsim_net_get_netgrou
  	return hwsim_net->netgroup;
  }
  
 -static inline void hwsim_net_set_netgroup(struct net *net)
 +static inline int hwsim_net_set_netgroup(struct net *net)
  {
  	struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
  
 -	hwsim_net->netgroup = hwsim_netgroup++;
 +	hwsim_net->netgroup = ida_simple_get(&hwsim_netgroup_ida,
 +					     0, 0, GFP_KERNEL);
 +	return hwsim_net->netgroup >= 0 ? 0 : -ENOMEM;
  }
  
  static inline u32 hwsim_net_get_wmediumd(struct net *net)
@@@ -495,7 -493,6 +495,7 @@@ static LIST_HEAD(hwsim_radios)
  static struct workqueue_struct *hwsim_wq;
  static struct rhashtable hwsim_radios_rht;
  static int hwsim_radio_idx;
 +static int hwsim_radios_generation = 1;
  
  static struct platform_driver mac80211_hwsim_driver = {
  	.driver = {
@@@ -640,7 -637,6 +640,7 @@@ static const struct nla_policy hwsim_ge
  	[HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
  	[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
  	[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
 +	[HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
  };
  
  static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@@ -2412,7 -2408,6 +2412,7 @@@ struct hwsim_new_radio_params 
  	bool destroy_on_close;
  	const char *hwname;
  	bool no_vif;
 +	const u8 *perm_addr;
  };
  
  static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@@ -2577,25 -2572,15 +2577,25 @@@ static int mac80211_hwsim_new_radio(str
  	skb_queue_head_init(&data->pending);
  
  	SET_IEEE80211_DEV(hw, data->dev);
 -	eth_zero_addr(addr);
 -	addr[0] = 0x02;
 -	addr[3] = idx >> 8;
 -	addr[4] = idx;
 -	memcpy(data->addresses[0].addr, addr, ETH_ALEN);
 -	memcpy(data->addresses[1].addr, addr, ETH_ALEN);
 -	data->addresses[1].addr[0] |= 0x40;
 -	hw->wiphy->n_addresses = 2;
 -	hw->wiphy->addresses = data->addresses;
 +	if (!param->perm_addr) {
 +		eth_zero_addr(addr);
 +		addr[0] = 0x02;
 +		addr[3] = idx >> 8;
 +		addr[4] = idx;
 +		memcpy(data->addresses[0].addr, addr, ETH_ALEN);
 +		/* Why need here second address ? */
 +		data->addresses[1].addr[0] |= 0x40;
 +		memcpy(data->addresses[1].addr, addr, ETH_ALEN);
 +		hw->wiphy->n_addresses = 2;
 +		hw->wiphy->addresses = data->addresses;
 +		/* possible address clash is checked at hash table insertion */
 +	} else {
 +		memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
 +		/* compatibility with automatically generated mac addr */
 +		memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
 +		hw->wiphy->n_addresses = 2;
 +		hw->wiphy->addresses = data->addresses;
 +	}
  
  	data->channels = param->channels;
  	data->use_chanctx = param->use_chanctx;
@@@ -2742,6 -2727,7 +2742,7 @@@
  	mutex_init(&data->mutex);
  
  	data->netgroup = hwsim_net_get_netgroup(net);
+ 	data->wmediumd = hwsim_net_get_wmediumd(net);
  
  	/* Enable frame retransmissions for lossy channels */
  	hw->max_rates = 4;
@@@ -2800,17 -2786,13 +2801,17 @@@
  	err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
  				     hwsim_rht_params);
  	if (err < 0) {
 -		pr_debug("mac80211_hwsim: radio index %d already present\n",
 -			 idx);
 +		if (info) {
 +			GENL_SET_ERR_MSG(info, "perm addr already present");
 +			NL_SET_BAD_ATTR(info->extack,
 +					info->attrs[HWSIM_ATTR_PERM_ADDR]);
 +		}
  		spin_unlock_bh(&hwsim_radio_lock);
  		goto failed_final_insert;
  	}
  
  	list_add_tail(&data->list, &hwsim_radios);
 +	hwsim_radios_generation++;
  	spin_unlock_bh(&hwsim_radio_lock);
  
  	if (idx > 0)
@@@ -3229,19 -3211,6 +3230,19 @@@ static int hwsim_new_radio_nl(struct sk
  		param.regd = hwsim_world_regdom_custom[idx];
  	}
  
 +	if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
 +		if (!is_valid_ether_addr(
 +				nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
 +			GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
 +			NL_SET_BAD_ATTR(info->extack,
 +					info->attrs[HWSIM_ATTR_PERM_ADDR]);
 +			return -EINVAL;
 +		}
 +
 +
 +		param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
 +	}
 +
  	ret = mac80211_hwsim_new_radio(info, &param);
  	kfree(hwname);
  	return ret;
@@@ -3281,7 -3250,6 +3282,7 @@@ static int hwsim_del_radio_nl(struct sk
  		list_del(&data->list);
  		rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
  				       hwsim_rht_params);
 +		hwsim_radios_generation++;
  		spin_unlock_bh(&hwsim_radio_lock);
  		mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
  					 info);
@@@ -3338,19 -3306,17 +3339,19 @@@ out_err
  static int hwsim_dump_radio_nl(struct sk_buff *skb,
  			       struct netlink_callback *cb)
  {
 -	int idx = cb->args[0];
 +	int last_idx = cb->args[0];
  	struct mac80211_hwsim_data *data = NULL;
 -	int res;
 +	int res = 0;
 +	void *hdr;
  
  	spin_lock_bh(&hwsim_radio_lock);
 +	cb->seq = hwsim_radios_generation;
  
 -	if (idx == hwsim_radio_idx)
 +	if (last_idx >= hwsim_radio_idx-1)
  		goto done;
  
  	list_for_each_entry(data, &hwsim_radios, list) {
 -		if (data->idx < idx)
 +		if (data->idx <= last_idx)
  			continue;
  
  		if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
@@@ -3363,25 -3329,14 +3364,25 @@@
  		if (res < 0)
  			break;
  
 -		idx = data->idx + 1;
 +		last_idx = data->idx;
  	}
  
 -	cb->args[0] = idx;
 +	cb->args[0] = last_idx;
 +
 +	/* list changed, but no new element sent, set interrupted flag */
 +	if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
 +		hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
 +				  cb->nlh->nlmsg_seq, &hwsim_genl_family,
 +				  NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
 +		if (!hdr)
 +			res = -EMSGSIZE;
 +		genl_dump_check_consistent(cb, hdr);
 +		genlmsg_end(skb, hdr);
 +	}
  
  done:
  	spin_unlock_bh(&hwsim_radio_lock);
 -	return skb->len;
 +	return res ?: skb->len;
  }
  
  /* Generic Netlink operations array */
@@@ -3439,7 -3394,6 +3440,7 @@@ static void destroy_radio(struct work_s
  	struct mac80211_hwsim_data *data =
  		container_of(work, struct mac80211_hwsim_data, destroy_work);
  
 +	hwsim_radios_generation++;
  	mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
  }
  
@@@ -3509,7 -3463,9 +3510,7 @@@ failure
  
  static __net_init int hwsim_init_net(struct net *net)
  {
 -	hwsim_net_set_netgroup(net);
 -
 -	return 0;
 +	return hwsim_net_set_netgroup(net);
  }
  
  static void __net_exit hwsim_exit_net(struct net *net)
@@@ -3532,8 -3488,6 +3533,8 @@@
  		queue_work(hwsim_wq, &data->destroy_work);
  	}
  	spin_unlock_bh(&hwsim_radio_lock);
 +
 +	ida_simple_remove(&hwsim_netgroup_ida, hwsim_net_get_netgroup(net));
  }
  
  static struct pernet_operations hwsim_net_ops = {
@@@ -3541,7 -3495,6 +3542,7 @@@
  	.exit = hwsim_exit_net,
  	.id   = &hwsim_net_id,
  	.size = sizeof(struct hwsim_net),
 +	.async = true,
  };
  
  static void hwsim_exit_netlink(void)
diff --combined drivers/s390/net/qeth_core_main.c
index 8c97ce2516bb,3653bea38470..19203340f879
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@@ -527,8 -527,7 +527,7 @@@ static inline int qeth_is_cq(struct qet
  	    queue == card->qdio.no_in_queues - 1;
  }
  
- 
- static int qeth_issue_next_read(struct qeth_card *card)
+ static int __qeth_issue_next_read(struct qeth_card *card)
  {
  	int rc;
  	struct qeth_cmd_buffer *iob;
@@@ -559,6 -558,17 +558,17 @@@
  	return rc;
  }
  
+ static int qeth_issue_next_read(struct qeth_card *card)
+ {
+ 	int ret;
+ 
+ 	spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+ 	ret = __qeth_issue_next_read(card);
+ 	spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+ 
+ 	return ret;
+ }
+ 
  static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
  {
  	struct qeth_reply *reply;
@@@ -708,8 -718,11 +718,8 @@@ static int qeth_check_idx_response(stru
  
  	QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN);
  	if ((buffer[2] & 0xc0) == 0xc0) {
 -		QETH_DBF_MESSAGE(2, "received an IDX TERMINATE "
 -			   "with cause code 0x%02x%s\n",
 -			   buffer[4],
 -			   ((buffer[4] == 0x22) ?
 -			    " -- try another portname" : ""));
 +		QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#02x\n",
 +				 buffer[4]);
  		QETH_CARD_TEXT(card, 2, "ckidxres");
  		QETH_CARD_TEXT(card, 2, " idxterm");
  		QETH_CARD_TEXT_(card, 2, "  rc%d", -EIO);
@@@ -957,7 -970,7 +967,7 @@@ void qeth_clear_thread_running_bit(stru
  	spin_lock_irqsave(&card->thread_mask_lock, flags);
  	card->thread_running_mask &= ~thread;
  	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
- 	wake_up(&card->wait_q);
+ 	wake_up_all(&card->wait_q);
  }
  EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
  
@@@ -1161,6 -1174,7 +1171,7 @@@ static void qeth_irq(struct ccw_device 
  		}
  		rc = qeth_get_problem(cdev, irb);
  		if (rc) {
+ 			card->read_or_write_problem = 1;
  			qeth_clear_ipacmd_list(card);
  			qeth_schedule_recovery(card);
  			goto out;
@@@ -1179,7 -1193,7 +1190,7 @@@
  		return;
  	if (channel == &card->read &&
  	    channel->state == CH_STATE_UP)
- 		qeth_issue_next_read(card);
+ 		__qeth_issue_next_read(card);
  
  	iob = channel->iob;
  	index = channel->buf_no;
@@@ -2835,8 -2849,7 +2846,8 @@@ static int qeth_init_input_buffer(struc
  	int i;
  
  	if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
 -		buf->rx_skb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN);
 +		buf->rx_skb = netdev_alloc_skb(card->dev,
 +					       QETH_RX_PULL_LEN + ETH_HLEN);
  		if (!buf->rx_skb)
  			return 1;
  	}
@@@ -2873,8 -2886,8 +2884,8 @@@ int qeth_init_qdio_queues(struct qeth_c
  	QETH_DBF_TEXT(SETUP, 2, "initqdqs");
  
  	/* inbound queue */
 -	qdio_reset_buffers(card->qdio.in_q->qdio_bufs,
 -			   QDIO_MAX_BUFFERS_PER_Q);
 +	qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
 +	memset(&card->rx, 0, sizeof(struct qeth_rx));
  	qeth_initialize_working_pool_list(card);
  	/*give only as many buffers to hardware as we have buffer pool entries*/
  	for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
@@@ -2949,10 -2962,12 +2960,10 @@@ struct qeth_cmd_buffer *qeth_get_ipacmd
  		enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
  {
  	struct qeth_cmd_buffer *iob;
 -	struct qeth_ipa_cmd *cmd;
  
  	iob = qeth_get_buffer(&card->write);
  	if (iob) {
 -		cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 -		qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);
 +		qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot);
  	} else {
  		dev_warn(&card->gdev->dev,
  			 "The qeth driver ran out of channel command buffers\n");
@@@ -3063,7 -3078,7 +3074,7 @@@ static struct qeth_cmd_buffer *qeth_get
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS,
  				     QETH_PROT_IPV4);
  	if (iob) {
 -		cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +		cmd = __ipa_cmd(iob);
  		cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
  		cmd->data.setadapterparms.hdr.command_code = command;
  		cmd->data.setadapterparms.hdr.used_total = 1;
@@@ -3205,7 -3220,7 +3216,7 @@@ static int qeth_query_setdiagass(struc
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.diagass.subcmd_len = 16;
  	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
  	return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
@@@ -3258,7 -3273,7 +3269,7 @@@ int qeth_hw_trap(struct qeth_card *card
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.diagass.subcmd_len = 80;
  	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
  	cmd->data.diagass.type = 1;
@@@ -4236,7 -4251,7 +4247,7 @@@ void qeth_setadp_promisc_mode(struct qe
  			sizeof(struct qeth_ipacmd_setadpparms_hdr) + 8);
  	if (!iob)
  		return;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setadapterparms.data.mode = mode;
  	qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
  }
@@@ -4303,7 -4318,7 +4314,7 @@@ int qeth_setadpparms_change_macaddr(str
  				   sizeof(struct qeth_change_addr));
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
  	cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN;
  	ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr,
@@@ -4418,7 -4433,7 +4429,7 @@@ static int qeth_setadpparms_set_access_
  				   sizeof(struct qeth_set_access_ctrl));
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
  	access_ctrl_req->subcmd_code = isolation;
  
@@@ -4664,7 -4679,7 +4675,7 @@@ static int qeth_snmp_command(struct qet
  		rc = -ENOMEM;
  		goto out;
  	}
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
  	rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
  				    qeth_snmp_command_cb, (void *)&qinfo);
@@@ -4749,7 -4764,7 +4760,7 @@@ static int qeth_query_oat_command(struc
  		rc = -ENOMEM;
  		goto out_free;
  	}
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	oat_req = &cmd->data.setadapterparms.data.query_oat;
  	oat_req->subcmd_code = oat_data.command;
  
@@@ -5083,8 -5098,6 +5094,6 @@@ static void qeth_core_free_card(struct 
  	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
  	qeth_clean_channel(&card->read);
  	qeth_clean_channel(&card->write);
- 	if (card->dev)
- 		free_netdev(card->dev);
  	qeth_free_qdio_buffers(card);
  	unregister_service_level(&card->qeth_service_level);
  	kfree(card);
@@@ -5326,7 -5339,7 +5335,7 @@@ struct sk_buff *qeth_core_get_next_skb(
  	} else {
  		unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;
  
 -		skb = dev_alloc_skb(linear + headroom);
 +		skb = napi_alloc_skb(&card->napi, linear + headroom);
  	}
  	if (!skb)
  		goto no_mem;
@@@ -5490,7 -5503,7 +5499,7 @@@ struct qeth_cmd_buffer *qeth_get_setass
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
  
  	if (iob) {
 -		cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +		cmd = __ipa_cmd(iob);
  		cmd->data.setassparms.hdr.assist_no = ipa_func;
  		cmd->data.setassparms.hdr.length = 8 + len;
  		cmd->data.setassparms.hdr.command_code = cmd_code;
@@@ -5513,7 -5526,7 +5522,7 @@@ int qeth_send_setassparms(struct qeth_c
  
  	QETH_CARD_TEXT(card, 4, "sendassp");
  
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	if (len <= sizeof(__u32))
  		cmd->data.setassparms.data.flags_32bit = (__u32) data;
  	else   /* (len > sizeof(__u32)) */
diff --combined drivers/s390/net/qeth_l2_main.c
index 8f5babdccb42,5ef4c978ad19..50a313806dde
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@@ -108,7 -108,7 +108,7 @@@ static int qeth_l2_send_setdelmac(struc
  	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setdelmac.mac_length = ETH_ALEN;
  	ether_addr_copy(cmd->data.setdelmac.mac, mac);
  	return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob,
@@@ -305,7 -305,7 +305,7 @@@ static int qeth_l2_send_setdelvlan(stru
  	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setdelvlan.vlan_id = i;
  	return qeth_setdelvlan_makerc(card, qeth_send_ipa_cmd(card, iob,
  					    qeth_l2_send_setdelvlan_cb, NULL));
@@@ -437,8 -437,10 +437,8 @@@ static int qeth_l2_process_inbound_buff
  			*done = 1;
  			break;
  		}
 -		skb->dev = card->dev;
  		switch (hdr->hdr.l2.id) {
  		case QETH_HEADER_TYPE_LAYER2:
 -			skb->pkt_type = PACKET_HOST;
  			skb->protocol = eth_type_trans(skb, skb->dev);
  			if ((card->dev->features & NETIF_F_RXCSUM)
  			   && ((hdr->hdr.l2.flags[1] &
@@@ -913,8 -915,8 +913,8 @@@ static void qeth_l2_remove_device(struc
  		qeth_l2_set_offline(cgdev);
  
  	if (card->dev) {
- 		netif_napi_del(&card->napi);
  		unregister_netdev(card->dev);
+ 		free_netdev(card->dev);
  		card->dev = NULL;
  	}
  	return;
@@@ -973,7 -975,6 +973,7 @@@ static int qeth_l2_setup_netdev(struct 
  		return -ENODEV;
  
  	card->dev->ml_priv = card;
 +	card->dev->priv_flags |= IFF_UNICAST_FLT;
  	card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
  	card->dev->mtu = card->info.initial_mtu;
  	card->dev->min_mtu = 64;
@@@ -990,16 -991,9 +990,16 @@@
  		card->dev->features |= NETIF_F_VLAN_CHALLENGED;
  	else
  		card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 +
 +	if (card->info.type != QETH_CARD_TYPE_OSN &&
 +	    card->info.type != QETH_CARD_TYPE_IQD) {
 +		card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 +		card->dev->needed_headroom = sizeof(struct qeth_hdr);
 +		card->dev->hw_features |= NETIF_F_SG;
 +		card->dev->vlan_features |= NETIF_F_SG;
 +	}
 +
  	if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
 -		card->dev->hw_features = NETIF_F_SG;
 -		card->dev->vlan_features = NETIF_F_SG;
  		card->dev->features |= NETIF_F_SG;
  		/* OSA 3S and earlier has no RX/TX support */
  		if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) {
@@@ -1011,6 -1005,11 +1011,6 @@@
  			card->dev->vlan_features |= NETIF_F_RXCSUM;
  		}
  	}
 -	if (card->info.type != QETH_CARD_TYPE_OSN &&
 -	    card->info.type != QETH_CARD_TYPE_IQD) {
 -		card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 -		card->dev->needed_headroom = sizeof(struct qeth_hdr);
 -	}
  
  	card->info.broadcast_capable = 1;
  	qeth_l2_request_initial_mac(card);
@@@ -1087,6 -1086,7 +1087,6 @@@ static int __qeth_l2_set_online(struct 
  	qeth_l2_setup_bridgeport_attrs(card);
  
  	card->state = CARD_STATE_HARDSETUP;
 -	memset(&card->rx, 0, sizeof(struct qeth_rx));
  	qeth_print_status_message(card);
  
  	/* softsetup */
@@@ -1374,6 -1374,7 +1374,6 @@@ int qeth_osn_assist(struct net_device *
  {
  	struct qeth_cmd_buffer *iob;
  	struct qeth_card *card;
 -	int rc;
  
  	if (!dev)
  		return -ENODEV;
@@@ -1384,8 -1385,9 +1384,8 @@@
  	if (!qeth_card_hw_is_reachable(card))
  		return -ENODEV;
  	iob = qeth_wait_for_buffer(&card->write);
 -	memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
 -	rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
 -	return rc;
 +	memcpy(__ipa_cmd(iob), data, data_len);
 +	return qeth_osn_send_ipa_cmd(card, iob, data_len);
  }
  EXPORT_SYMBOL(qeth_osn_assist);
  
@@@ -1762,7 -1764,7 +1762,7 @@@ static struct qeth_cmd_buffer *qeth_sbp
  	iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0);
  	if (!iob)
  		return iob;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) +
  				      cmd_length;
  	cmd->data.sbp.hdr.command_code = sbp_cmd;
@@@ -2127,7 -2129,7 +2127,7 @@@ static int qeth_l2_vnicc_request(struc
  		return -ENOMEM;
  
  	/* create header for request */
 -	cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	req = &cmd->data.vnicc;
  
  	/* create sub command header for request */
diff --combined drivers/s390/net/qeth_l3_main.c
index ef3f548b7d35,b6b12220da71..c1a16a74aa83
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@@ -67,15 -67,6 +67,15 @@@ void qeth_l3_ipaddr_to_string(enum qeth
  		qeth_l3_ipaddr6_to_string(addr, buf);
  }
  
 +static struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions prot)
 +{
 +	struct qeth_ipaddr *addr = kmalloc(sizeof(*addr), GFP_ATOMIC);
 +
 +	if (addr)
 +		qeth_l3_init_ipaddr(addr, QETH_IP_TYPE_NORMAL, prot);
 +	return addr;
 +}
 +
  static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
  						   struct qeth_ipaddr *query)
  {
@@@ -147,18 -138,12 +147,18 @@@ static bool qeth_l3_is_addr_covered_by_
  	return rc;
  }
  
 -int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
 +static int qeth_l3_delete_ip(struct qeth_card *card,
 +			     struct qeth_ipaddr *tmp_addr)
  {
  	int rc = 0;
  	struct qeth_ipaddr *addr;
  
 -	QETH_CARD_TEXT(card, 4, "delip");
 +	if (tmp_addr->type == QETH_IP_TYPE_RXIP)
 +		QETH_CARD_TEXT(card, 2, "delrxip");
 +	else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
 +		QETH_CARD_TEXT(card, 2, "delvipa");
 +	else
 +		QETH_CARD_TEXT(card, 2, "delip");
  
  	if (tmp_addr->proto == QETH_PROT_IPV4)
  		QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
@@@ -186,18 -171,13 +186,18 @@@
  	return rc;
  }
  
 -int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
 +static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
  {
  	int rc = 0;
  	struct qeth_ipaddr *addr;
  	char buf[40];
  
 -	QETH_CARD_TEXT(card, 4, "addip");
 +	if (tmp_addr->type == QETH_IP_TYPE_RXIP)
 +		QETH_CARD_TEXT(card, 2, "addrxip");
 +	else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
 +		QETH_CARD_TEXT(card, 2, "addvipa");
 +	else
 +		QETH_CARD_TEXT(card, 2, "addip");
  
  	if (tmp_addr->proto == QETH_PROT_IPV4)
  		QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
@@@ -229,7 -209,7 +229,7 @@@
  
  		if (qeth_l3_is_addr_covered_by_ipato(card, addr)) {
  			QETH_CARD_TEXT(card, 2, "tkovaddr");
 -			addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
 +			addr->ipato = 1;
  		}
  		hash_add(card->ip_htable, &addr->hnode,
  				qeth_l3_ipaddr_hash(addr));
@@@ -271,6 -251,23 +271,6 @@@
  	return rc;
  }
  
 -
 -struct qeth_ipaddr *qeth_l3_get_addr_buffer(
 -				enum qeth_prot_versions prot)
 -{
 -	struct qeth_ipaddr *addr;
 -
 -	addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
 -	if (!addr)
 -		return NULL;
 -
 -	addr->type = QETH_IP_TYPE_NORMAL;
 -	addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
 -	addr->proto = prot;
 -
 -	return addr;
 -}
 -
  static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover)
  {
  	struct qeth_ipaddr *addr;
@@@ -355,7 -352,7 +355,7 @@@ static int qeth_l3_send_setdelmc(struc
  	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	ether_addr_copy(cmd->data.setdelipm.mac, addr->mac);
  	if (addr->proto == QETH_PROT_IPV6)
  		memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
@@@ -382,38 -379,21 +382,38 @@@ static void qeth_l3_fill_netmask(u8 *ne
  	}
  }
  
 +static u32 qeth_l3_get_setdelip_flags(struct qeth_ipaddr *addr, bool set)
 +{
 +	switch (addr->type) {
 +	case QETH_IP_TYPE_RXIP:
 +		return (set) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
 +	case QETH_IP_TYPE_VIPA:
 +		return (set) ? QETH_IPA_SETIP_VIPA_FLAG :
 +			       QETH_IPA_DELIP_VIPA_FLAG;
 +	default:
 +		return (set && addr->ipato) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
 +	}
 +}
 +
  static int qeth_l3_send_setdelip(struct qeth_card *card,
 -		struct qeth_ipaddr *addr, int ipacmd, unsigned int flags)
 +				 struct qeth_ipaddr *addr,
 +				 enum qeth_ipa_cmds ipacmd)
  {
 -	int rc;
  	struct qeth_cmd_buffer *iob;
  	struct qeth_ipa_cmd *cmd;
  	__u8 netmask[16];
 +	u32 flags;
  
  	QETH_CARD_TEXT(card, 4, "setdelip");
 -	QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
  
  	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
 +
 +	flags = qeth_l3_get_setdelip_flags(addr, ipacmd == IPA_CMD_SETIP);
 +	QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
 +
  	if (addr->proto == QETH_PROT_IPV6) {
  		memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
  		       sizeof(struct in6_addr));
@@@ -427,7 -407,9 +427,7 @@@
  		cmd->data.setdelip4.flags = flags;
  	}
  
 -	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
 -
 -	return rc;
 +	return qeth_send_ipa_cmd(card, iob, NULL, NULL);
  }
  
  static int qeth_l3_send_setrouting(struct qeth_card *card,
@@@ -441,7 -423,7 +441,7 @@@
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setrtg.type = (type);
  	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
  
@@@ -543,7 -525,10 +543,7 @@@ void qeth_l3_update_ipato(struct qeth_c
  	hash_for_each(card->ip_htable, i, addr, hnode) {
  		if (addr->type != QETH_IP_TYPE_NORMAL)
  			continue;
 -		if (qeth_l3_is_addr_covered_by_ipato(card, addr))
 -			addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
 -		else
 -			addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
 +		addr->ipato = qeth_l3_is_addr_covered_by_ipato(card, addr);
  	}
  }
  
@@@ -621,39 -606,132 +621,39 @@@ int qeth_l3_del_ipato_entry(struct qeth
  	return rc;
  }
  
 -/*
 - * VIPA related functions
 - */
 -int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
 -	      const u8 *addr)
 -{
 -	struct qeth_ipaddr *ipaddr;
 -	int rc;
 -
 -	ipaddr = qeth_l3_get_addr_buffer(proto);
 -	if (ipaddr) {
 -		if (proto == QETH_PROT_IPV4) {
 -			QETH_CARD_TEXT(card, 2, "addvipa4");
 -			memcpy(&ipaddr->u.a4.addr, addr, 4);
 -			ipaddr->u.a4.mask = 0;
 -		} else if (proto == QETH_PROT_IPV6) {
 -			QETH_CARD_TEXT(card, 2, "addvipa6");
 -			memcpy(&ipaddr->u.a6.addr, addr, 16);
 -			ipaddr->u.a6.pfxlen = 0;
 -		}
 -		ipaddr->type = QETH_IP_TYPE_VIPA;
 -		ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
 -		ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
 -	} else
 -		return -ENOMEM;
 -
 -	spin_lock_bh(&card->ip_lock);
 -	rc = qeth_l3_add_ip(card, ipaddr);
 -	spin_unlock_bh(&card->ip_lock);
 -
 -	kfree(ipaddr);
 -
 -	return rc;
 -}
 -
 -int qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
 -		     const u8 *addr)
 -{
 -	struct qeth_ipaddr *ipaddr;
 -	int rc;
 -
 -	ipaddr = qeth_l3_get_addr_buffer(proto);
 -	if (ipaddr) {
 -		if (proto == QETH_PROT_IPV4) {
 -			QETH_CARD_TEXT(card, 2, "delvipa4");
 -			memcpy(&ipaddr->u.a4.addr, addr, 4);
 -			ipaddr->u.a4.mask = 0;
 -		} else if (proto == QETH_PROT_IPV6) {
 -			QETH_CARD_TEXT(card, 2, "delvipa6");
 -			memcpy(&ipaddr->u.a6.addr, addr, 16);
 -			ipaddr->u.a6.pfxlen = 0;
 -		}
 -		ipaddr->type = QETH_IP_TYPE_VIPA;
 -	} else
 -		return -ENOMEM;
 -
 -	spin_lock_bh(&card->ip_lock);
 -	rc = qeth_l3_delete_ip(card, ipaddr);
 -	spin_unlock_bh(&card->ip_lock);
 -
 -	kfree(ipaddr);
 -	return rc;
 -}
 -
 -/*
 - * proxy ARP related functions
 - */
 -int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
 -	      const u8 *addr)
 +int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip,
 +			     enum qeth_ip_types type,
 +			     enum qeth_prot_versions proto)
  {
 -	struct qeth_ipaddr *ipaddr;
 +	struct qeth_ipaddr addr;
  	int rc;
  
 -	ipaddr = qeth_l3_get_addr_buffer(proto);
 -	if (ipaddr) {
 -		if (proto == QETH_PROT_IPV4) {
 -			QETH_CARD_TEXT(card, 2, "addrxip4");
 -			memcpy(&ipaddr->u.a4.addr, addr, 4);
 -			ipaddr->u.a4.mask = 0;
 -		} else if (proto == QETH_PROT_IPV6) {
 -			QETH_CARD_TEXT(card, 2, "addrxip6");
 -			memcpy(&ipaddr->u.a6.addr, addr, 16);
 -			ipaddr->u.a6.pfxlen = 0;
 -		}
 -
 -		ipaddr->type = QETH_IP_TYPE_RXIP;
 -		ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
 -		ipaddr->del_flags = 0;
 -	} else
 -		return -ENOMEM;
 +	qeth_l3_init_ipaddr(&addr, type, proto);
 +	if (proto == QETH_PROT_IPV4)
 +		memcpy(&addr.u.a4.addr, ip, 4);
 +	else
 +		memcpy(&addr.u.a6.addr, ip, 16);
  
  	spin_lock_bh(&card->ip_lock);
 -	rc = qeth_l3_add_ip(card, ipaddr);
 +	rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
  	spin_unlock_bh(&card->ip_lock);
 -
 -	kfree(ipaddr);
 -
  	return rc;
  }
  
 -int qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
 -		     const u8 *addr)
 +int qeth_l3_modify_hsuid(struct qeth_card *card, bool add)
  {
 -	struct qeth_ipaddr *ipaddr;
 -	int rc;
 +	struct qeth_ipaddr addr;
 +	int rc, i;
  
 -	ipaddr = qeth_l3_get_addr_buffer(proto);
 -	if (ipaddr) {
 -		if (proto == QETH_PROT_IPV4) {
 -			QETH_CARD_TEXT(card, 2, "delrxip4");
 -			memcpy(&ipaddr->u.a4.addr, addr, 4);
 -			ipaddr->u.a4.mask = 0;
 -		} else if (proto == QETH_PROT_IPV6) {
 -			QETH_CARD_TEXT(card, 2, "delrxip6");
 -			memcpy(&ipaddr->u.a6.addr, addr, 16);
 -			ipaddr->u.a6.pfxlen = 0;
 -		}
 -		ipaddr->type = QETH_IP_TYPE_RXIP;
 -	} else
 -		return -ENOMEM;
 +	qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
 +	addr.u.a6.addr.s6_addr[0] = 0xfe;
 +	addr.u.a6.addr.s6_addr[1] = 0x80;
 +	for (i = 0; i < 8; i++)
 +		addr.u.a6.addr.s6_addr[8+i] = card->options.hsuid[i];
  
  	spin_lock_bh(&card->ip_lock);
 -	rc = qeth_l3_delete_ip(card, ipaddr);
 +	rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
  	spin_unlock_bh(&card->ip_lock);
 -
 -	kfree(ipaddr);
  	return rc;
  }
  
@@@ -680,7 -758,8 +680,7 @@@ static int qeth_l3_register_addr_entry(
  		if (addr->is_multicast)
  			rc =  qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM);
  		else
 -			rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP,
 -					addr->set_flags);
 +			rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP);
  		if (rc)
  			QETH_CARD_TEXT(card, 2, "failed");
  	} while ((--cnt > 0) && rc);
@@@ -712,7 -791,8 +712,7 @@@ static int qeth_l3_deregister_addr_entr
  	if (addr->is_multicast)
  		rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM);
  	else
 -		rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP,
 -					addr->del_flags);
 +		rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP);
  	if (rc)
  		QETH_CARD_TEXT(card, 2, "failed");
  
@@@ -992,7 -1072,7 +992,7 @@@ static int qeth_l3_iqd_read_initial_mac
  				     QETH_PROT_IPV6);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
  			card->info.unique_id;
  
@@@ -1037,7 -1117,7 +1037,7 @@@ static int qeth_l3_get_unique_id(struc
  				     QETH_PROT_IPV6);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
  			card->info.unique_id;
  
@@@ -1113,7 -1193,7 +1113,7 @@@ qeth_diags_trace(struct qeth_card *card
  	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.diagass.subcmd_len = 16;
  	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
  	cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
@@@ -1422,24 -1502,30 +1422,24 @@@ static void qeth_l3_rebuild_skb(struct 
  				ipv6_eth_mc_map(&ipv6_hdr(skb)->daddr, tg_addr);
  
  			card->stats.multicast++;
 -			skb->pkt_type = PACKET_MULTICAST;
  			break;
  		case QETH_CAST_BROADCAST:
  			ether_addr_copy(tg_addr, card->dev->broadcast);
  			card->stats.multicast++;
 -			skb->pkt_type = PACKET_BROADCAST;
  			break;
 -		case QETH_CAST_UNICAST:
 -		case QETH_CAST_ANYCAST:
 -		case QETH_CAST_NOCAST:
  		default:
  			if (card->options.sniffer)
  				skb->pkt_type = PACKET_OTHERHOST;
 -			else
 -				skb->pkt_type = PACKET_HOST;
  			ether_addr_copy(tg_addr, card->dev->dev_addr);
  		}
 +
  		if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
  			card->dev->header_ops->create(skb, card->dev, prot,
  				tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac,
 -				card->dev->addr_len);
 +				skb->len);
  		else
  			card->dev->header_ops->create(skb, card->dev, prot,
 -				tg_addr, "FAKELL", card->dev->addr_len);
 +				tg_addr, "FAKELL", skb->len);
  	}
  
  	skb->protocol = eth_type_trans(skb, card->dev);
@@@ -1486,16 -1572,20 +1486,16 @@@ static int qeth_l3_process_inbound_buff
  			*done = 1;
  			break;
  		}
 -		skb->dev = card->dev;
  		switch (hdr->hdr.l3.id) {
  		case QETH_HEADER_TYPE_LAYER3:
  			magic = *(__u16 *)skb->data;
  			if ((card->info.type == QETH_CARD_TYPE_IQD) &&
  			    (magic == ETH_P_AF_IUCV)) {
  				skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
 -				skb->pkt_type = PACKET_HOST;
 -				skb->mac_header = NET_SKB_PAD;
 -				skb->dev = card->dev;
  				len = skb->len;
  				card->dev->header_ops->create(skb, card->dev, 0,
 -					card->dev->dev_addr, "FAKELL",
 -					card->dev->addr_len);
 +					card->dev->dev_addr, "FAKELL", len);
 +				skb_reset_mac_header(skb);
  				netif_receive_skb(skb);
  			} else {
  				qeth_l3_rebuild_skb(card, skb, hdr);
@@@ -1504,6 -1594,7 +1504,6 @@@
  			}
  			break;
  		case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
 -			skb->pkt_type = PACKET_HOST;
  			skb->protocol = eth_type_trans(skb, skb->dev);
  			len = skb->len;
  			netif_receive_skb(skb);
@@@ -1522,6 -1613,69 +1522,6 @@@
  	return work_done;
  }
  
 -static int qeth_l3_verify_vlan_dev(struct net_device *dev,
 -			struct qeth_card *card)
 -{
 -	int rc = 0;
 -	u16 vid;
 -
 -	for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) {
 -		struct net_device *netdev;
 -
 -		rcu_read_lock();
 -		netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q),
 -					      vid);
 -		rcu_read_unlock();
 -		if (netdev == dev) {
 -			rc = QETH_VLAN_CARD;
 -			break;
 -		}
 -	}
 -
 -	if (rc && !(vlan_dev_real_dev(dev)->ml_priv == (void *)card))
 -		return 0;
 -
 -	return rc;
 -}
 -
 -static int qeth_l3_verify_dev(struct net_device *dev)
 -{
 -	struct qeth_card *card;
 -	int rc = 0;
 -	unsigned long flags;
 -
 -	read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
 -	list_for_each_entry(card, &qeth_core_card_list.list, list) {
 -		if (card->dev == dev) {
 -			rc = QETH_REAL_CARD;
 -			break;
 -		}
 -		rc = qeth_l3_verify_vlan_dev(dev, card);
 -		if (rc)
 -			break;
 -	}
 -	read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
 -
 -	return rc;
 -}
 -
 -static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
 -{
 -	struct qeth_card *card = NULL;
 -	int rc;
 -
 -	rc = qeth_l3_verify_dev(dev);
 -	if (rc == QETH_REAL_CARD)
 -		card = dev->ml_priv;
 -	else if (rc == QETH_VLAN_CARD)
 -		card = vlan_dev_real_dev(dev)->ml_priv;
 -	if (card && card->options.layer2)
 -		card = NULL;
 -	if (card)
 -		QETH_CARD_TEXT_(card, 4, "%d", rc);
 -	return card ;
 -}
 -
  static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
  {
  	QETH_DBF_TEXT(SETUP, 2, "stopcard");
@@@ -1850,7 -2004,7 +1850,7 @@@ static int qeth_l3_query_arp_cache_info
  				       prot);
  	if (!iob)
  		return -ENOMEM;
 -	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 +	cmd = __ipa_cmd(iob);
  	cmd->data.setassparms.data.query_arp.request_bits = 0x000F;
  	cmd->data.setassparms.data.query_arp.reply_bits = 0;
  	cmd->data.setassparms.data.query_arp.no_entries = 0;
@@@ -2631,16 -2785,14 +2631,16 @@@ static int qeth_l3_setup_netdev(struct 
  			if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
  				card->dev->dev_id = card->info.unique_id &
  							 0xffff;
 +
 +			card->dev->hw_features |= NETIF_F_SG;
 +			card->dev->vlan_features |= NETIF_F_SG;
 +
  			if (!card->info.guestlan) {
 -				card->dev->hw_features = NETIF_F_SG |
 -					NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
 -					NETIF_F_TSO;
 -				card->dev->vlan_features = NETIF_F_SG |
 -					NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
 -					NETIF_F_TSO;
  				card->dev->features |= NETIF_F_SG;
 +				card->dev->hw_features |= NETIF_F_TSO |
 +					NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
 +				card->dev->vlan_features |= NETIF_F_TSO |
 +					NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
  			}
  		}
  	} else if (card->info.type == QETH_CARD_TYPE_IQD) {
@@@ -2713,8 -2865,8 +2713,8 @@@ static void qeth_l3_remove_device(struc
  		qeth_l3_set_offline(cgdev);
  
  	if (card->dev) {
- 		netif_napi_del(&card->napi);
  		unregister_netdev(card->dev);
+ 		free_netdev(card->dev);
  		card->dev = NULL;
  	}
  
@@@ -2755,6 -2907,7 +2755,6 @@@ static int __qeth_l3_set_online(struct 
  		card->info.hwtrap = 0;
  
  	card->state = CARD_STATE_HARDSETUP;
 -	memset(&card->rx, 0, sizeof(struct qeth_rx));
  	qeth_print_status_message(card);
  
  	/* softsetup */
@@@ -2977,43 -3130,13 +2977,43 @@@ struct qeth_discipline qeth_l3_discipli
  };
  EXPORT_SYMBOL_GPL(qeth_l3_discipline);
  
 +static int qeth_l3_handle_ip_event(struct qeth_card *card,
 +				   struct qeth_ipaddr *addr,
 +				   unsigned long event)
 +{
 +	switch (event) {
 +	case NETDEV_UP:
 +		spin_lock_bh(&card->ip_lock);
 +		qeth_l3_add_ip(card, addr);
 +		spin_unlock_bh(&card->ip_lock);
 +		return NOTIFY_OK;
 +	case NETDEV_DOWN:
 +		spin_lock_bh(&card->ip_lock);
 +		qeth_l3_delete_ip(card, addr);
 +		spin_unlock_bh(&card->ip_lock);
 +		return NOTIFY_OK;
 +	default:
 +		return NOTIFY_DONE;
 +	}
 +}
 +
 +static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
 +{
 +	if (is_vlan_dev(dev))
 +		dev = vlan_dev_real_dev(dev);
 +	if (dev->netdev_ops == &qeth_l3_osa_netdev_ops ||
 +	    dev->netdev_ops == &qeth_l3_netdev_ops)
 +		return (struct qeth_card *) dev->ml_priv;
 +	return NULL;
 +}
 +
  static int qeth_l3_ip_event(struct notifier_block *this,
  			    unsigned long event, void *ptr)
  {
  
  	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
 -	struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
 -	struct qeth_ipaddr *addr;
 +	struct net_device *dev = ifa->ifa_dev->dev;
 +	struct qeth_ipaddr addr;
  	struct qeth_card *card;
  
  	if (dev_net(dev) != &init_net)
@@@ -3024,11 -3147,29 +3024,11 @@@
  		return NOTIFY_DONE;
  	QETH_CARD_TEXT(card, 3, "ipevent");
  
 -	addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
 -	if (addr) {
 -		addr->u.a4.addr = be32_to_cpu(ifa->ifa_address);
 -		addr->u.a4.mask = be32_to_cpu(ifa->ifa_mask);
 -		addr->type = QETH_IP_TYPE_NORMAL;
 -	} else
 -		return NOTIFY_DONE;
 -
 -	switch (event) {
 -	case NETDEV_UP:
 -		spin_lock_bh(&card->ip_lock);
 -		qeth_l3_add_ip(card, addr);
 -		spin_unlock_bh(&card->ip_lock);
 -		break;
 -	case NETDEV_DOWN:
 -		spin_lock_bh(&card->ip_lock);
 -		qeth_l3_delete_ip(card, addr);
 -		spin_unlock_bh(&card->ip_lock);
 -		break;
 -	}
 +	qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV4);
 +	addr.u.a4.addr = be32_to_cpu(ifa->ifa_address);
 +	addr.u.a4.mask = be32_to_cpu(ifa->ifa_mask);
  
 -	kfree(addr);
 -	return NOTIFY_DONE;
 +	return qeth_l3_handle_ip_event(card, &addr, event);
  }
  
  static struct notifier_block qeth_l3_ip_notifier = {
@@@ -3040,8 -3181,8 +3040,8 @@@ static int qeth_l3_ip6_event(struct not
  			     unsigned long event, void *ptr)
  {
  	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
 -	struct net_device *dev = (struct net_device *)ifa->idev->dev;
 -	struct qeth_ipaddr *addr;
 +	struct net_device *dev = ifa->idev->dev;
 +	struct qeth_ipaddr addr;
  	struct qeth_card *card;
  
  	card = qeth_l3_get_card_from_dev(dev);
@@@ -3051,11 -3192,29 +3051,11 @@@
  	if (!qeth_is_supported(card, IPA_IPV6))
  		return NOTIFY_DONE;
  
 -	addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
 -	if (addr) {
 -		memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
 -		addr->u.a6.pfxlen = ifa->prefix_len;
 -		addr->type = QETH_IP_TYPE_NORMAL;
 -	} else
 -		return NOTIFY_DONE;
 -
 -	switch (event) {
 -	case NETDEV_UP:
 -		spin_lock_bh(&card->ip_lock);
 -		qeth_l3_add_ip(card, addr);
 -		spin_unlock_bh(&card->ip_lock);
 -		break;
 -	case NETDEV_DOWN:
 -		spin_lock_bh(&card->ip_lock);
 -		qeth_l3_delete_ip(card, addr);
 -		spin_unlock_bh(&card->ip_lock);
 -		break;
 -	}
 +	qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
 +	addr.u.a6.addr = ifa->addr;
 +	addr.u.a6.pfxlen = ifa->prefix_len;
  
 -	kfree(addr);
 -	return NOTIFY_DONE;
 +	return qeth_l3_handle_ip_event(card, &addr, event);
  }
  
  static struct notifier_block qeth_l3_ip6_notifier = {
diff --combined drivers/vhost/net.c
index b5fb56b822fd,8139bc70ad7d..a31d9b240af8
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@@ -170,7 -170,7 +170,7 @@@ static void vhost_net_buf_unproduce(str
  	if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) {
  		ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head,
  				   vhost_net_buf_get_size(rxq),
- 				   __skb_array_destroy_skb);
+ 				   tun_ptr_free);
  		rxq->head = rxq->tail = 0;
  	}
  }
@@@ -948,6 -948,7 +948,7 @@@ static int vhost_net_open(struct inode 
  		n->vqs[i].done_idx = 0;
  		n->vqs[i].vhost_hlen = 0;
  		n->vqs[i].sock_hlen = 0;
+ 		n->vqs[i].rx_ring = NULL;
  		vhost_net_buf_init(&n->vqs[i].rxq);
  	}
  	vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
@@@ -972,6 -973,7 +973,7 @@@ static struct socket *vhost_net_stop_vq
  	vhost_net_disable_vq(n, vq);
  	vq->private_data = NULL;
  	vhost_net_buf_unproduce(nvq);
+ 	nvq->rx_ring = NULL;
  	mutex_unlock(&vq->mutex);
  	return sock;
  }
@@@ -1038,7 -1040,7 +1040,7 @@@ static struct socket *get_raw_socket(in
  		struct sockaddr_ll sa;
  		char  buf[MAX_ADDR_LEN];
  	} uaddr;
 -	int uaddr_len = sizeof uaddr, r;
 +	int r;
  	struct socket *sock = sockfd_lookup(fd, &r);
  
  	if (!sock)
@@@ -1050,8 -1052,9 +1052,8 @@@
  		goto err;
  	}
  
 -	r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
 -			       &uaddr_len, 0);
 -	if (r)
 +	r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 0);
 +	if (r < 0)
  		goto err;
  
  	if (uaddr.sa.sll_family != AF_PACKET) {
@@@ -1160,14 -1163,14 +1162,14 @@@ static long vhost_net_set_backend(struc
  		vhost_net_disable_vq(n, vq);
  		vq->private_data = sock;
  		vhost_net_buf_unproduce(nvq);
- 		if (index == VHOST_NET_VQ_RX)
- 			nvq->rx_ring = get_tap_ptr_ring(fd);
  		r = vhost_vq_init_access(vq);
  		if (r)
  			goto err_used;
  		r = vhost_net_enable_vq(n, vq);
  		if (r)
  			goto err_used;
+ 		if (index == VHOST_NET_VQ_RX)
+ 			nvq->rx_ring = get_tap_ptr_ring(fd);
  
  		oldubufs = nvq->ubufs;
  		nvq->ubufs = ubufs;
diff --combined include/linux/mlx5/driver.h
index 4814cad7456e,9d3a03364e6e..cded85ab6fe4
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@@ -345,6 -345,13 +345,6 @@@ struct mlx5_buf_list 
  	dma_addr_t		map;
  };
  
 -struct mlx5_buf {
 -	struct mlx5_buf_list	direct;
 -	int			npages;
 -	int			size;
 -	u8			page_shift;
 -};
 -
  struct mlx5_frag_buf {
  	struct mlx5_buf_list	*frags;
  	int			npages;
@@@ -352,15 -359,6 +352,15 @@@
  	u8			page_shift;
  };
  
 +struct mlx5_frag_buf_ctrl {
 +	struct mlx5_frag_buf	frag_buf;
 +	u32			sz_m1;
 +	u32			frag_sz_m1;
 +	u8			log_sz;
 +	u8			log_stride;
 +	u8			log_frag_strides;
 +};
 +
  struct mlx5_eq_tasklet {
  	struct list_head list;
  	struct list_head process_list;
@@@ -377,18 -375,11 +377,18 @@@ struct mlx5_eq_pagefault 
  	mempool_t		*pool;
  };
  
 +struct mlx5_cq_table {
 +	/* protect radix tree */
 +	spinlock_t		lock;
 +	struct radix_tree_root	tree;
 +};
 +
  struct mlx5_eq {
  	struct mlx5_core_dev   *dev;
 +	struct mlx5_cq_table	cq_table;
  	__be32 __iomem	       *doorbell;
  	u32			cons_index;
 -	struct mlx5_buf		buf;
 +	struct mlx5_frag_buf	buf;
  	int			size;
  	unsigned int		irqn;
  	u8			eqn;
@@@ -462,8 -453,8 +462,8 @@@ struct mlx5_core_srq 
  	struct mlx5_core_rsc_common	common; /* must be first */
  	u32		srqn;
  	int		max;
- 	int		max_gs;
- 	int		max_avail_gather;
+ 	size_t		max_gs;
+ 	size_t		max_avail_gather;
  	int		wqe_shift;
  	void (*event)	(struct mlx5_core_srq *, enum mlx5_event);
  
@@@ -535,6 -526,13 +535,6 @@@ struct mlx5_core_health 
  	struct delayed_work		recover_work;
  };
  
 -struct mlx5_cq_table {
 -	/* protect radix tree
 -	 */
 -	spinlock_t		lock;
 -	struct radix_tree_root	tree;
 -};
 -
  struct mlx5_qp_table {
  	/* protect radix tree
  	 */
@@@ -656,6 -654,10 +656,6 @@@ struct mlx5_priv 
  	struct dentry	       *cmdif_debugfs;
  	/* end: qp staff */
  
 -	/* start: cq staff */
 -	struct mlx5_cq_table	cq_table;
 -	/* end: cq staff */
 -
  	/* start: mkey staff */
  	struct mlx5_mkey_table	mkey_table;
  	/* end: mkey staff */
@@@ -934,9 -936,9 +934,9 @@@ struct mlx5_hca_vport_context 
  	bool			grh_required;
  };
  
 -static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset)
 +static inline void *mlx5_buf_offset(struct mlx5_frag_buf *buf, int offset)
  {
 -		return buf->direct.buf + offset;
 +		return buf->frags->buf + offset;
  }
  
  #define STRUCT_FIELD(header, field) \
@@@ -975,25 -977,6 +975,25 @@@ static inline u32 mlx5_base_mkey(const 
  	return key & 0xffffff00u;
  }
  
 +static inline void mlx5_core_init_cq_frag_buf(struct mlx5_frag_buf_ctrl *fbc,
 +					      void *cqc)
 +{
 +	fbc->log_stride	= 6 + MLX5_GET(cqc, cqc, cqe_sz);
 +	fbc->log_sz	= MLX5_GET(cqc, cqc, log_cq_size);
 +	fbc->sz_m1	= (1 << fbc->log_sz) - 1;
 +	fbc->log_frag_strides = PAGE_SHIFT - fbc->log_stride;
 +	fbc->frag_sz_m1	= (1 << fbc->log_frag_strides) - 1;
 +}
 +
 +static inline void *mlx5_frag_buf_get_wqe(struct mlx5_frag_buf_ctrl *fbc,
 +					  u32 ix)
 +{
 +	unsigned int frag = (ix >> fbc->log_frag_strides);
 +
 +	return fbc->frag_buf.frags[frag].buf +
 +		((fbc->frag_sz_m1 & ix) << fbc->log_stride);
 +}
 +
  int mlx5_cmd_init(struct mlx5_core_dev *dev);
  void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
  void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
@@@ -1019,10 -1002,9 +1019,10 @@@ void mlx5_drain_health_wq(struct mlx5_c
  void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
  void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
  int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
 -			struct mlx5_buf *buf, int node);
 -int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf);
 -void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf);
 +			struct mlx5_frag_buf *buf, int node);
 +int mlx5_buf_alloc(struct mlx5_core_dev *dev,
 +		   int size, struct mlx5_frag_buf *buf);
 +void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
  int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size,
  			     struct mlx5_frag_buf *buf, int node);
  void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
@@@ -1067,12 -1049,22 +1067,12 @@@ int mlx5_satisfy_startup_pages(struct m
  int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev);
  void mlx5_register_debugfs(void);
  void mlx5_unregister_debugfs(void);
 -int mlx5_eq_init(struct mlx5_core_dev *dev);
 -void mlx5_eq_cleanup(struct mlx5_core_dev *dev);
 -void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas);
 +
 +void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas);
  void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas);
 -void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn);
  void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
  void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
  struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
 -void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced);
 -void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type);
 -int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
 -		       int nent, u64 mask, const char *name,
 -		       enum mlx5_eq_type type);
 -int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 -int mlx5_start_eqs(struct mlx5_core_dev *dev);
 -void mlx5_stop_eqs(struct mlx5_core_dev *dev);
  int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
  		    unsigned int *irqn);
  int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
@@@ -1084,6 -1076,14 +1084,6 @@@ int mlx5_core_access_reg(struct mlx5_co
  			 int size_in, void *data_out, int size_out,
  			 u16 reg_num, int arg, int write);
  
 -int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 -void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 -int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
 -		       u32 *out, int outlen);
 -int mlx5_eq_debugfs_init(struct mlx5_core_dev *dev);
 -void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev);
 -int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev);
 -void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev);
  int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db);
  int mlx5_db_alloc_node(struct mlx5_core_dev *dev, struct mlx5_db *db,
  		       int node);
@@@ -1224,12 -1224,6 +1224,12 @@@ static inline int mlx5_core_is_pf(struc
  	return !(dev->priv.pci_dev_data & MLX5_PCI_DEV_IS_VF);
  }
  
 +#define MLX5_TOTAL_VPORTS(mdev) (1 + pci_sriov_get_totalvfs((mdev)->pdev))
 +#define MLX5_VPORT_MANAGER(mdev) \
 +	(MLX5_CAP_GEN(mdev, vport_group_manager) && \
 +	 (MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) && \
 +	 mlx5_core_is_pf(mdev))
 +
  static inline int mlx5_get_gid_table_len(u16 param)
  {
  	if (param > 4) {
diff --combined include/linux/net.h
index 000d1aada74f,2a0391eea05c..2248a052061d
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@@ -146,7 -146,7 +146,7 @@@ struct proto_ops 
  				      struct socket *newsock, int flags, bool kern);
  	int		(*getname)   (struct socket *sock,
  				      struct sockaddr *addr,
 -				      int *sockaddr_len, int peer);
 +				      int peer);
  	__poll_t	(*poll)	     (struct file *file, struct socket *sock,
  				      struct poll_table_struct *wait);
  	int		(*ioctl)     (struct socket *sock, unsigned int cmd,
@@@ -222,6 -222,7 +222,7 @@@ enum 
  int sock_wake_async(struct socket_wq *sk_wq, int how, int band);
  int sock_register(const struct net_proto_family *fam);
  void sock_unregister(int family);
+ bool sock_is_registered(int family);
  int __sock_create(struct net *net, int family, int type, int proto,
  		  struct socket **res, int kern);
  int sock_create(int family, int type, int proto, struct socket **res);
@@@ -294,8 -295,10 +295,8 @@@ int kernel_listen(struct socket *sock, 
  int kernel_accept(struct socket *sock, struct socket **newsock, int flags);
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
  		   int flags);
 -int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
 -		       int *addrlen);
 -int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
 -		       int *addrlen);
 +int kernel_getsockname(struct socket *sock, struct sockaddr *addr);
 +int kernel_getpeername(struct socket *sock, struct sockaddr *addr);
  int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval,
  		      int *optlen);
  int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval,
diff --combined include/linux/phy.h
index 5a9b1753fdc5,7c4c2379e010..f0b5870a6d40
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@@ -984,6 -984,10 +984,10 @@@ static inline int genphy_no_soft_reset(
  {
  	return 0;
  }
+ int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad,
+ 				u16 regnum);
+ int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
+ 				 u16 regnum, u16 val);
  
  /* Clause 45 PHY */
  int genphy_c45_restart_aneg(struct phy_device *phydev);
@@@ -995,14 -999,6 +999,14 @@@ int genphy_c45_pma_setup_forced(struct 
  int genphy_c45_an_disable_aneg(struct phy_device *phydev);
  int genphy_c45_read_mdix(struct phy_device *phydev);
  
 +/* The gen10g_* functions are the old Clause 45 stub */
 +int gen10g_config_aneg(struct phy_device *phydev);
 +int gen10g_read_status(struct phy_device *phydev);
 +int gen10g_no_soft_reset(struct phy_device *phydev);
 +int gen10g_config_init(struct phy_device *phydev);
 +int gen10g_suspend(struct phy_device *phydev);
 +int gen10g_resume(struct phy_device *phydev);
 +
  static inline int phy_read_status(struct phy_device *phydev)
  {
  	if (!phydev->drv)
@@@ -1020,7 -1016,6 +1024,6 @@@ int phy_driver_register(struct phy_driv
  int phy_drivers_register(struct phy_driver *new_driver, int n,
  			 struct module *owner);
  void phy_state_machine(struct work_struct *work);
- void phy_change(struct phy_device *phydev);
  void phy_change_work(struct work_struct *work);
  void phy_mac_interrupt(struct phy_device *phydev);
  void phy_start_machine(struct phy_device *phydev);
diff --combined include/linux/skbuff.h
index d8340e6e8814,99df17109e1b..47082f54ec1f
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@@ -466,9 -466,6 +466,9 @@@ struct ubuf_info 
  
  #define skb_uarg(SKB)	((struct ubuf_info *)(skb_shinfo(SKB)->destructor_arg))
  
 +int mm_account_pinned_pages(struct mmpin *mmp, size_t size);
 +void mm_unaccount_pinned_pages(struct mmpin *mmp);
 +
  struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size);
  struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size,
  					struct ubuf_info *uarg);
@@@ -4040,6 -4037,12 +4040,12 @@@ static inline bool skb_is_gso_v6(const 
  	return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
  }
  
+ /* Note: Should be called only if skb_is_gso(skb) is true */
+ static inline bool skb_is_gso_sctp(const struct sk_buff *skb)
+ {
+ 	return skb_shinfo(skb)->gso_type & SKB_GSO_SCTP;
+ }
+ 
  static inline void skb_gso_reset(struct sk_buff *skb)
  {
  	skb_shinfo(skb)->gso_size = 0;
@@@ -4047,6 -4050,22 +4053,22 @@@
  	skb_shinfo(skb)->gso_type = 0;
  }
  
+ static inline void skb_increase_gso_size(struct skb_shared_info *shinfo,
+ 					 u16 increment)
+ {
+ 	if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS))
+ 		return;
+ 	shinfo->gso_size += increment;
+ }
+ 
+ static inline void skb_decrease_gso_size(struct skb_shared_info *shinfo,
+ 					 u16 decrement)
+ {
+ 	if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS))
+ 		return;
+ 	shinfo->gso_size -= decrement;
+ }
+ 
  void __skb_warn_lro_forwarding(const struct sk_buff *skb);
  
  static inline bool skb_warn_if_lro(const struct sk_buff *skb)
diff --combined include/net/ip.h
index d53b5a9eae34,f49b3a576bec..36f8f7811093
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@@ -91,17 -91,6 +91,17 @@@ static inline int inet_sdif(struct sk_b
  	return 0;
  }
  
 +/* Special input handler for packets caught by router alert option.
 +   They are selected only by protocol field, and then processed likely
 +   local ones; but only if someone wants them! Otherwise, router
 +   not running rsvpd will kill RSVP.
 +
 +   It is user level problem, what it will make with them.
 +   I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
 +   but receiver should be enough clever f.e. to forward mtrace requests,
 +   sent to multicast group to reach destination designated router.
 + */
 +
  struct ip_ra_chain {
  	struct ip_ra_chain __rcu *next;
  	struct sock		*sk;
@@@ -112,6 -101,8 +112,6 @@@
  	struct rcu_head		rcu;
  };
  
 -extern struct ip_ra_chain __rcu *ip_ra_chain;
 -
  /* IP flags. */
  #define IP_CE		0x8000		/* Flag: "Congestion"		*/
  #define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
@@@ -195,15 -186,15 +195,15 @@@ int ip4_datagram_connect(struct sock *s
  void ip4_datagram_release_cb(struct sock *sk);
  
  struct ip_reply_arg {
 -	struct kvec iov[1];   
 +	struct kvec iov[1];
  	int	    flags;
  	__wsum 	    csum;
  	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
 -				/* -1 if not needed */ 
 +				/* -1 if not needed */
  	int	    bound_dev_if;
  	u8  	    tos;
  	kuid_t	    uid;
 -}; 
 +};
  
  #define IP_REPLY_ARG_NOSRCCHECK 1
  
@@@ -337,6 -328,13 +337,13 @@@ int ip_decrease_ttl(struct iphdr *iph
  	return --iph->ttl;
  }
  
+ static inline int ip_mtu_locked(const struct dst_entry *dst)
+ {
+ 	const struct rtable *rt = (const struct rtable *)dst;
+ 
+ 	return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
+ }
+ 
  static inline
  int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
  {
@@@ -344,7 -342,7 +351,7 @@@
  
  	return  pmtudisc == IP_PMTUDISC_DO ||
  		(pmtudisc == IP_PMTUDISC_WANT &&
- 		 !(dst_metric_locked(dst, RTAX_MTU)));
+ 		 !ip_mtu_locked(dst));
  }
  
  static inline bool ip_sk_accept_pmtu(const struct sock *sk)
@@@ -370,7 -368,7 +377,7 @@@ static inline unsigned int ip_dst_mtu_m
  	struct net *net = dev_net(dst->dev);
  
  	if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
- 	    dst_metric_locked(dst, RTAX_MTU) ||
+ 	    ip_mtu_locked(dst) ||
  	    !forwarding)
  		return dst_mtu(dst);
  
@@@ -586,13 -584,13 +593,13 @@@ int ip_frag_mem(struct net *net)
  /*
   *	Functions provided by ip_forward.c
   */
 - 
 +
  int ip_forward(struct sk_buff *skb);
 - 
 +
  /*
   *	Functions provided by ip_options.c
   */
 - 
 +
  void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
  		      __be32 daddr, struct rtable *rt, int is_frag);
  
diff --combined include/net/ip6_route.h
index ce2abc0ff102,ac0866bb9e93..0084013d6bed
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@@ -75,8 -75,7 +75,8 @@@ static inline bool rt6_qualify_for_ecmp
  void ip6_route_input(struct sk_buff *skb);
  struct dst_entry *ip6_route_input_lookup(struct net *net,
  					 struct net_device *dev,
 -					 struct flowi6 *fl6, int flags);
 +					 struct flowi6 *fl6,
 +					 const struct sk_buff *skb, int flags);
  
  struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
  					 struct flowi6 *fl6, int flags);
@@@ -89,10 -88,9 +89,10 @@@ static inline struct dst_entry *ip6_rou
  }
  
  struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
 -				   int flags);
 +				   const struct sk_buff *skb, int flags);
  struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 -			       int ifindex, struct flowi6 *fl6, int flags);
 +			       int ifindex, struct flowi6 *fl6,
 +			       const struct sk_buff *skb, int flags);
  
  void ip6_route_init_special_entries(void);
  int ip6_route_init(void);
@@@ -128,10 -126,8 +128,10 @@@ static inline int ip6_route_get_saddr(s
  }
  
  struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
 -			    const struct in6_addr *saddr, int oif, int flags);
 -u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb);
 +			    const struct in6_addr *saddr, int oif,
 +			    const struct sk_buff *skb, int flags);
 +u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
 +		       const struct sk_buff *skb, struct flow_keys *hkeys);
  
  struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);
  
@@@ -183,6 -179,9 +183,9 @@@ void rt6_disable_ip(struct net_device *
  void rt6_sync_down_dev(struct net_device *dev, unsigned long event);
  void rt6_multipath_rebalance(struct rt6_info *rt);
  
+ void rt6_uncached_list_add(struct rt6_info *rt);
+ void rt6_uncached_list_del(struct rt6_info *rt);
+ 
  static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb)
  {
  	const struct dst_entry *dst = skb_dst(skb);
@@@ -270,5 -269,4 +273,5 @@@ static inline bool rt6_duplicate_nextho
  	       ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
  	       !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
  }
 +
  #endif
diff --combined include/net/ip_fib.h
index 7c7522e8585b,77d0a78cf7d2..81d0f2107ff1
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@@ -59,6 -59,7 +59,7 @@@ struct fib_nh_exception 
  	int				fnhe_genid;
  	__be32				fnhe_daddr;
  	u32				fnhe_pmtu;
+ 	bool				fnhe_mtu_locked;
  	__be32				fnhe_gw;
  	unsigned long			fnhe_expires;
  	struct rtable __rcu		*fnhe_rth_input;
@@@ -157,7 -158,7 +158,7 @@@ struct fib_result_nl 
  	unsigned char	nh_sel;
  	unsigned char	type;
  	unsigned char	scope;
 -	int             err;      
 +	int             err;
  };
  
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
@@@ -293,13 -294,6 +294,13 @@@ static inline unsigned int fib4_rules_s
  	return 0;
  }
  
 +static inline bool fib4_rules_early_flow_dissect(struct net *net,
 +						 struct sk_buff *skb,
 +						 struct flowi4 *fl4,
 +						 struct flow_keys *flkeys)
 +{
 +	return false;
 +}
  #else /* CONFIG_IP_MULTIPLE_TABLES */
  int __net_init fib4_rules_init(struct net *net);
  void __net_exit fib4_rules_exit(struct net *net);
@@@ -348,24 -342,6 +349,24 @@@ bool fib4_rule_default(const struct fib
  int fib4_rules_dump(struct net *net, struct notifier_block *nb);
  unsigned int fib4_rules_seq_read(struct net *net);
  
 +static inline bool fib4_rules_early_flow_dissect(struct net *net,
 +						 struct sk_buff *skb,
 +						 struct flowi4 *fl4,
 +						 struct flow_keys *flkeys)
 +{
 +	unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
 +
 +	if (!net->ipv4.fib_rules_require_fldissect)
 +		return false;
 +
 +	skb_flow_dissect_flow_keys(skb, flkeys, flag);
 +	fl4->fl4_sport = flkeys->ports.src;
 +	fl4->fl4_dport = flkeys->ports.dst;
 +	fl4->flowi4_proto = flkeys->basic.ip_proto;
 +
 +	return true;
 +}
 +
  #endif /* CONFIG_IP_MULTIPLE_TABLES */
  
  /* Exported by fib_frontend.c */
@@@ -395,8 -371,8 +396,8 @@@ int fib_sync_down_addr(struct net_devic
  int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
  
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
 -int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
 -		       const struct sk_buff *skb);
 +int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 +		       const struct sk_buff *skb, struct flow_keys *flkeys);
  #endif
  void fib_select_multipath(struct fib_result *res, int hash);
  void fib_select_path(struct net *net, struct fib_result *res,
diff --combined include/net/mac80211.h
index 2fd59ed3be00,2b581bd93812..2449982daf75
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@@ -6,7 -6,6 +6,7 @@@
   * Copyright 2007-2010	Johannes Berg <johannes at sipsolutions.net>
   * Copyright 2013-2014  Intel Mobile Communications GmbH
   * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
 + * Copyright (C) 2018        Intel Corporation
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -935,7 -934,6 +935,7 @@@ struct ieee80211_tx_info 
  			u8 ampdu_len;
  			u8 antenna;
  			u16 tx_time;
 +			bool is_valid_ack_signal;
  			void *status_driver_data[19 / sizeof(void *)];
  		} status;
  		struct {
@@@ -1100,9 -1098,6 +1100,9 @@@ ieee80211_tx_info_clear_status(struct i
   *	the first subframe.
   * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
   *	be done in the hardware.
 + * @RX_FLAG_AMPDU_EOF_BIT: Value of the EOF bit in the A-MPDU delimiter for this
 + *	frame
 + * @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known
   */
  enum mac80211_rx_flags {
  	RX_FLAG_MMIC_ERROR		= BIT(0),
@@@ -1129,8 -1124,6 +1129,8 @@@
  	RX_FLAG_MIC_STRIPPED		= BIT(21),
  	RX_FLAG_ALLOW_SAME_PN		= BIT(22),
  	RX_FLAG_ICV_STRIPPED		= BIT(23),
 +	RX_FLAG_AMPDU_EOF_BIT		= BIT(24),
 +	RX_FLAG_AMPDU_EOF_BIT_KNOWN	= BIT(25),
  };
  
  /**
@@@ -2070,13 -2063,8 +2070,16 @@@ struct ieee80211_txq 
   * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
   *	TDLS links.
   *
 + * @IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP: The driver requires the
 + *	mgd_prepare_tx() callback to be called before transmission of a
 + *	deauthentication frame in case the association was completed but no
 + *	beacon was heard. This is required in multi-channel scenarios, where the
 + *	virtual interface might not be given air time for the transmission of
 + *	the frame, as it is not synced with the AP/P2P GO yet, and thus the
 + *	deauthentication frame might not be transmitted.
++ >
+  * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't
+  *	support QoS NDP for AP probing - that's most likely a driver bug.
   *
   * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
   */
@@@ -2121,7 -2109,7 +2124,8 @@@ enum ieee80211_hw_flags 
  	IEEE80211_HW_REPORTS_LOW_ACK,
  	IEEE80211_HW_SUPPORTS_TX_FRAG,
  	IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
 +	IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
+ 	IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP,
  
  	/* keep last, obviously */
  	NUM_IEEE80211_HW_FLAGS
@@@ -3366,9 -3354,6 +3370,9 @@@ enum ieee80211_reconfig_type 
   *	management frame prior to having successfully associated to allow the
   *	driver to give it channel time for the transmission, to get a response
   *	and to be able to synchronize with the GO.
 + *	For drivers that set %IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, mac80211
 + *	would also call this function before transmitting a deauthentication
 + *	frame in case that no beacon was heard from the AP/P2P GO.
   *	The callback will be called before each transmission and upon return
   *	mac80211 will transmit the frame right away.
   *	The callback is optional and can (should!) sleep.
diff --combined include/net/route.h
index 158833ea7988,20a92ca9e115..dbb032d5921b
--- a/include/net/route.h
+++ b/include/net/route.h
@@@ -63,8 -63,11 +63,9 @@@ struct rtable 
  	__be32			rt_gateway;
  
  	/* Miscellaneous cached information */
- 	u32			rt_pmtu;
+ 	u32			rt_mtu_locked:1,
+ 				rt_pmtu:31;
  
 -	u32			rt_table_id;
 -
  	struct list_head	rt_uncached;
  	struct uncached_list	*rt_uncached_list;
  };
@@@ -225,6 -228,9 +226,9 @@@ struct in_ifaddr
  void fib_add_ifaddr(struct in_ifaddr *);
  void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);
  
+ void rt_add_uncached_list(struct rtable *rt);
+ void rt_del_uncached_list(struct rtable *rt);
+ 
  static inline void ip_rt_put(struct rtable *rt)
  {
  	/* dst_release() accepts a NULL parameter.
diff --combined include/net/sch_generic.h
index d4907b584b38,2092d33194dd..493e311bbe93
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@@ -540,7 -540,7 +540,7 @@@ static inline bool skb_skip_tc_classify
  	return false;
  }
  
 -/* Reset all TX qdiscs greater then index of a device.  */
 +/* Reset all TX qdiscs greater than index of a device.  */
  static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
  {
  	struct Qdisc *qdisc;
@@@ -824,6 -824,16 +824,16 @@@ static inline void __qdisc_drop(struct 
  	*to_free = skb;
  }
  
+ static inline void __qdisc_drop_all(struct sk_buff *skb,
+ 				    struct sk_buff **to_free)
+ {
+ 	if (skb->prev)
+ 		skb->prev->next = *to_free;
+ 	else
+ 		skb->next = *to_free;
+ 	*to_free = skb;
+ }
+ 
  static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
  						   struct qdisc_skb_head *qh,
  						   struct sk_buff **to_free)
@@@ -956,6 -966,15 +966,15 @@@ static inline int qdisc_drop(struct sk_
  	return NET_XMIT_DROP;
  }
  
+ static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch,
+ 				 struct sk_buff **to_free)
+ {
+ 	__qdisc_drop_all(skb, to_free);
+ 	qdisc_qstats_drop(sch);
+ 
+ 	return NET_XMIT_DROP;
+ }
+ 
  /* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how
     long it will take to send a packet given its size.
   */
diff --combined include/net/sock.h
index b7c75e024e37,ae23f3b389ca..709311132d4c
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@@ -417,7 -417,6 +417,7 @@@ struct sock 
  	struct page_frag	sk_frag;
  	netdev_features_t	sk_route_caps;
  	netdev_features_t	sk_route_nocaps;
 +	netdev_features_t	sk_route_forced_caps;
  	int			sk_gso_type;
  	unsigned int		sk_gso_max_size;
  	gfp_t			sk_allocation;
@@@ -1138,6 -1137,7 +1138,7 @@@ struct proto 
  
  int proto_register(struct proto *prot, int alloc_slab);
  void proto_unregister(struct proto *prot);
+ int sock_load_diag_module(int family, int protocol);
  
  #ifdef SOCK_REFCNT_DEBUG
  static inline void sk_refcnt_debug_inc(struct sock *sk)
@@@ -1585,7 -1585,7 +1586,7 @@@ int sock_no_bind(struct socket *, struc
  int sock_no_connect(struct socket *, struct sockaddr *, int, int);
  int sock_no_socketpair(struct socket *, struct socket *);
  int sock_no_accept(struct socket *, struct socket *, int, bool);
 -int sock_no_getname(struct socket *, struct sockaddr *, int *, int);
 +int sock_no_getname(struct socket *, struct sockaddr *, int);
  __poll_t sock_no_poll(struct file *, struct socket *,
  			  struct poll_table_struct *);
  int sock_no_ioctl(struct socket *, unsigned int, unsigned long);
@@@ -1863,6 -1863,15 +1864,6 @@@ static inline void sk_nocaps_add(struc
  	sk->sk_route_caps &= ~flags;
  }
  
 -static inline bool sk_check_csum_caps(struct sock *sk)
 -{
 -	return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
 -	       (sk->sk_family == PF_INET &&
 -		(sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
 -	       (sk->sk_family == PF_INET6 &&
 -		(sk->sk_route_caps & NETIF_F_IPV6_CSUM));
 -}
 -
  static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
  					   struct iov_iter *from, char *to,
  					   int copy, int offset)
@@@ -2141,10 -2150,6 +2142,10 @@@ static inline struct page_frag *sk_page
  
  bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
  
 +int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
 +		int sg_start, int *sg_curr, unsigned int *sg_size,
 +		int first_coalesce);
 +
  /*
   *	Default write policy as shown to user space via poll/select/SIGIO
   */
diff --combined include/uapi/linux/if_ether.h
index 2e4a6c1accaa,820de5d222d2..3a45b4ad71a3
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@@ -30,6 -30,7 +30,7 @@@
   */
  
  #define ETH_ALEN	6		/* Octets in one ethernet addr	 */
+ #define ETH_TLEN	2		/* Octets in ethernet type field */
  #define ETH_HLEN	14		/* Total octets in header.	 */
  #define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
  #define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
@@@ -88,7 -89,6 +89,7 @@@
  #define ETH_P_AOE	0x88A2		/* ATA over Ethernet		*/
  #define ETH_P_8021AD	0x88A8          /* 802.1ad Service VLAN		*/
  #define ETH_P_802_EX1	0x88B5		/* 802.1 Local Experimental 1.  */
 +#define ETH_P_PREAUTH	0x88C7		/* 802.11 Preauthentication */
  #define ETH_P_TIPC	0x88CA		/* TIPC 			*/
  #define ETH_P_MACSEC	0x88E5		/* 802.1ae MACsec */
  #define ETH_P_8021AH	0x88E7          /* 802.1ah Backbone Service Tag */
diff --combined kernel/bpf/syscall.c
index 3aeb4ea2a93a,43f95d190eea..dd172ee16716
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@@ -1315,8 -1315,7 +1315,8 @@@ static int bpf_obj_get(const union bpf_
  
  #define BPF_PROG_ATTACH_LAST_FIELD attach_flags
  
 -static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
 +static int sockmap_get_from_fd(const union bpf_attr *attr,
 +			       int type, bool attach)
  {
  	struct bpf_prog *prog = NULL;
  	int ufd = attr->target_fd;
@@@ -1330,7 -1329,8 +1330,7 @@@
  		return PTR_ERR(map);
  
  	if (attach) {
 -		prog = bpf_prog_get_type(attr->attach_bpf_fd,
 -					 BPF_PROG_TYPE_SK_SKB);
 +		prog = bpf_prog_get_type(attr->attach_bpf_fd, type);
  		if (IS_ERR(prog)) {
  			fdput(f);
  			return PTR_ERR(prog);
@@@ -1382,11 -1382,9 +1382,11 @@@ static int bpf_prog_attach(const union 
  	case BPF_CGROUP_DEVICE:
  		ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
  		break;
 +	case BPF_SK_MSG_VERDICT:
 +		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, true);
  	case BPF_SK_SKB_STREAM_PARSER:
  	case BPF_SK_SKB_STREAM_VERDICT:
 -		return sockmap_get_from_fd(attr, true);
 +		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, true);
  	default:
  		return -EINVAL;
  	}
@@@ -1439,11 -1437,9 +1439,11 @@@ static int bpf_prog_detach(const union 
  	case BPF_CGROUP_DEVICE:
  		ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
  		break;
 +	case BPF_SK_MSG_VERDICT:
 +		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, false);
  	case BPF_SK_SKB_STREAM_PARSER:
  	case BPF_SK_SKB_STREAM_VERDICT:
 -		return sockmap_get_from_fd(attr, false);
 +		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, false);
  	default:
  		return -EINVAL;
  	}
@@@ -1849,7 -1845,7 +1849,7 @@@ SYSCALL_DEFINE3(bpf, int, cmd, union bp
  	union bpf_attr attr = {};
  	int err;
  
- 	if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
+ 	if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
  		return -EPERM;
  
  	err = check_uarg_tail_zero(uattr, sizeof(attr), size);
diff --combined kernel/trace/bpf_trace.c
index c634e093951f,01e6b3a38871..7f9691c86b6e
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@@ -661,7 -661,41 +661,41 @@@ static const struct bpf_func_proto bpf_
  	.arg3_type	= ARG_ANYTHING,
  };
  
- BPF_CALL_3(bpf_perf_prog_read_value_tp, struct bpf_perf_event_data_kern *, ctx,
+ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
+ {
+ 	switch (func_id) {
+ 	case BPF_FUNC_perf_event_output:
+ 		return &bpf_perf_event_output_proto_tp;
+ 	case BPF_FUNC_get_stackid:
+ 		return &bpf_get_stackid_proto_tp;
+ 	default:
+ 		return tracing_func_proto(func_id);
+ 	}
+ }
+ 
+ static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type,
+ 				    struct bpf_insn_access_aux *info)
+ {
+ 	if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
+ 		return false;
+ 	if (type != BPF_READ)
+ 		return false;
+ 	if (off % size != 0)
+ 		return false;
+ 
+ 	BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64));
+ 	return true;
+ }
+ 
+ const struct bpf_verifier_ops tracepoint_verifier_ops = {
+ 	.get_func_proto  = tp_prog_func_proto,
+ 	.is_valid_access = tp_prog_is_valid_access,
+ };
+ 
+ const struct bpf_prog_ops tracepoint_prog_ops = {
+ };
+ 
+ BPF_CALL_3(bpf_perf_prog_read_value, struct bpf_perf_event_data_kern *, ctx,
  	   struct bpf_perf_event_value *, buf, u32, size)
  {
  	int err = -EINVAL;
@@@ -678,8 -712,8 +712,8 @@@ clear
  	return err;
  }
  
- static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = {
-          .func           = bpf_perf_prog_read_value_tp,
+ static const struct bpf_func_proto bpf_perf_prog_read_value_proto = {
+          .func           = bpf_perf_prog_read_value,
           .gpl_only       = true,
           .ret_type       = RET_INTEGER,
           .arg1_type      = ARG_PTR_TO_CTX,
@@@ -687,7 -721,7 +721,7 @@@
           .arg3_type      = ARG_CONST_SIZE,
  };
  
- static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
+ static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id)
  {
  	switch (func_id) {
  	case BPF_FUNC_perf_event_output:
@@@ -695,38 -729,17 +729,16 @@@
  	case BPF_FUNC_get_stackid:
  		return &bpf_get_stackid_proto_tp;
  	case BPF_FUNC_perf_prog_read_value:
- 		return &bpf_perf_prog_read_value_proto_tp;
+ 		return &bpf_perf_prog_read_value_proto;
  	default:
  		return tracing_func_proto(func_id);
  	}
  }
  
- static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type,
- 				    struct bpf_insn_access_aux *info)
- {
- 	if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
- 		return false;
- 	if (type != BPF_READ)
- 		return false;
- 	if (off % size != 0)
- 		return false;
- 
- 	BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64));
- 	return true;
- }
- 
- const struct bpf_verifier_ops tracepoint_verifier_ops = {
- 	.get_func_proto  = tp_prog_func_proto,
- 	.is_valid_access = tp_prog_is_valid_access,
- };
- 
- const struct bpf_prog_ops tracepoint_prog_ops = {
- };
- 
  static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
  				    struct bpf_insn_access_aux *info)
  {
 -	const int size_sp = FIELD_SIZEOF(struct bpf_perf_event_data,
 -					 sample_period);
 +	const int size_u64 = sizeof(u64);
  
  	if (off < 0 || off >= sizeof(struct bpf_perf_event_data))
  		return false;
@@@ -737,13 -750,8 +749,13 @@@
  
  	switch (off) {
  	case bpf_ctx_range(struct bpf_perf_event_data, sample_period):
 -		bpf_ctx_record_field_size(info, size_sp);
 -		if (!bpf_ctx_narrow_access_ok(off, size, size_sp))
 +		bpf_ctx_record_field_size(info, size_u64);
 +		if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
 +			return false;
 +		break;
 +	case bpf_ctx_range(struct bpf_perf_event_data, addr):
 +		bpf_ctx_record_field_size(info, size_u64);
 +		if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
  			return false;
  		break;
  	default:
@@@ -770,14 -778,6 +782,14 @@@ static u32 pe_prog_convert_ctx_access(e
  				      bpf_target_off(struct perf_sample_data, period, 8,
  						     target_size));
  		break;
 +	case offsetof(struct bpf_perf_event_data, addr):
 +		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
 +						       data), si->dst_reg, si->src_reg,
 +				      offsetof(struct bpf_perf_event_data_kern, data));
 +		*insn++ = BPF_LDX_MEM(BPF_DW, si->dst_reg, si->dst_reg,
 +				      bpf_target_off(struct perf_sample_data, addr, 8,
 +						     target_size));
 +		break;
  	default:
  		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
  						       regs), si->dst_reg, si->src_reg,
@@@ -791,7 -791,7 +803,7 @@@
  }
  
  const struct bpf_verifier_ops perf_event_verifier_ops = {
- 	.get_func_proto		= tp_prog_func_proto,
+ 	.get_func_proto		= pe_prog_func_proto,
  	.is_valid_access	= pe_prog_is_valid_access,
  	.convert_ctx_access	= pe_prog_convert_ctx_access,
  };
diff --combined net/batman-adv/distributed-arp-table.c
index 75dda9454ccf,87cd962d28d5..a60bacf7120b
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/* Copyright (C) 2011-2017  B.A.T.M.A.N. contributors:
 +/* Copyright (C) 2011-2018  B.A.T.M.A.N. contributors:
   *
   * Antonio Quartulli
   *
@@@ -33,7 -33,6 +33,7 @@@
  #include <linux/kernel.h>
  #include <linux/kref.h>
  #include <linux/list.h>
 +#include <linux/netlink.h>
  #include <linux/rculist.h>
  #include <linux/rcupdate.h>
  #include <linux/seq_file.h>
@@@ -44,19 -43,13 +44,19 @@@
  #include <linux/string.h>
  #include <linux/workqueue.h>
  #include <net/arp.h>
 +#include <net/genetlink.h>
 +#include <net/netlink.h>
 +#include <net/sock.h>
 +#include <uapi/linux/batman_adv.h>
  
  #include "bridge_loop_avoidance.h"
  #include "hard-interface.h"
  #include "hash.h"
  #include "log.h"
 +#include "netlink.h"
  #include "originator.h"
  #include "send.h"
 +#include "soft-interface.h"
  #include "translation-table.h"
  #include "tvlv.h"
  
@@@ -400,7 -393,7 +400,7 @@@ static void batadv_dbg_arp(struct batad
  		   batadv_arp_hw_src(skb, hdr_size), &ip_src,
  		   batadv_arp_hw_dst(skb, hdr_size), &ip_dst);
  
- 	if (hdr_size == 0)
+ 	if (hdr_size < sizeof(struct batadv_unicast_packet))
  		return;
  
  	unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
@@@ -502,7 -495,7 +502,7 @@@ static bool batadv_is_orig_node_eligibl
  	 * the one with the lowest address
  	 */
  	if (tmp_max == max && max_orig_node &&
 -	    batadv_compare_eth(candidate->orig, max_orig_node->orig) > 0)
 +	    batadv_compare_eth(candidate->orig, max_orig_node->orig))
  		goto out;
  
  	ret = true;
@@@ -859,151 -852,6 +859,151 @@@ out
  #endif
  
  /**
 + * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
 + *  netlink socket
 + * @msg: buffer for the message
 + * @portid: netlink port
 + * @seq: Sequence number of netlink message
 + * @dat_entry: entry to dump
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
 +			    struct batadv_dat_entry *dat_entry)
 +{
 +	int msecs;
 +	void *hdr;
 +
 +	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
 +			  NLM_F_MULTI, BATADV_CMD_GET_DAT_CACHE);
 +	if (!hdr)
 +		return -ENOBUFS;
 +
 +	msecs = jiffies_to_msecs(jiffies - dat_entry->last_update);
 +
 +	if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
 +			    dat_entry->ip) ||
 +	    nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN,
 +		    dat_entry->mac_addr) ||
 +	    nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) ||
 +	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
 +		genlmsg_cancel(msg, hdr);
 +		return -EMSGSIZE;
 +	}
 +
 +	genlmsg_end(msg, hdr);
 +	return 0;
 +}
 +
 +/**
 + * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
 + *  a netlink socket
 + * @msg: buffer for the message
 + * @portid: netlink port
 + * @seq: Sequence number of netlink message
 + * @head: bucket to dump
 + * @idx_skip: How many entries to skip
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
 +			     struct hlist_head *head, int *idx_skip)
 +{
 +	struct batadv_dat_entry *dat_entry;
 +	int idx = 0;
 +
 +	rcu_read_lock();
 +	hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
 +		if (idx < *idx_skip)
 +			goto skip;
 +
 +		if (batadv_dat_cache_dump_entry(msg, portid, seq,
 +						dat_entry)) {
 +			rcu_read_unlock();
 +			*idx_skip = idx;
 +
 +			return -EMSGSIZE;
 +		}
 +
 +skip:
 +		idx++;
 +	}
 +	rcu_read_unlock();
 +
 +	return 0;
 +}
 +
 +/**
 + * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
 + * @msg: buffer for the message
 + * @cb: callback structure containing arguments
 + *
 + * Return: message length.
 + */
 +int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb)
 +{
 +	struct batadv_hard_iface *primary_if = NULL;
 +	int portid = NETLINK_CB(cb->skb).portid;
 +	struct net *net = sock_net(cb->skb->sk);
 +	struct net_device *soft_iface;
 +	struct batadv_hashtable *hash;
 +	struct batadv_priv *bat_priv;
 +	int bucket = cb->args[0];
 +	struct hlist_head *head;
 +	int idx = cb->args[1];
 +	int ifindex;
 +	int ret = 0;
 +
 +	ifindex = batadv_netlink_get_ifindex(cb->nlh,
 +					     BATADV_ATTR_MESH_IFINDEX);
 +	if (!ifindex)
 +		return -EINVAL;
 +
 +	soft_iface = dev_get_by_index(net, ifindex);
 +	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
 +		ret = -ENODEV;
 +		goto out;
 +	}
 +
 +	bat_priv = netdev_priv(soft_iface);
 +	hash = bat_priv->dat.hash;
 +
 +	primary_if = batadv_primary_if_get_selected(bat_priv);
 +	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
 +		ret = -ENOENT;
 +		goto out;
 +	}
 +
 +	while (bucket < hash->size) {
 +		head = &hash->table[bucket];
 +
 +		if (batadv_dat_cache_dump_bucket(msg, portid,
 +						 cb->nlh->nlmsg_seq, head,
 +						 &idx))
 +			break;
 +
 +		bucket++;
 +		idx = 0;
 +	}
 +
 +	cb->args[0] = bucket;
 +	cb->args[1] = idx;
 +
 +	ret = msg->len;
 +
 +out:
 +	if (primary_if)
 +		batadv_hardif_put(primary_if);
 +
 +	if (soft_iface)
 +		dev_put(soft_iface);
 +
 +	return ret;
 +}
 +
 +/**
   * batadv_arp_get_type() - parse an ARP packet and gets the type
   * @bat_priv: the bat priv with all the soft interface information
   * @skb: packet to analyse
diff --combined net/batman-adv/icmp_socket.c
index 7d5e9abb7a65,5daa3d50da17..55c358ad3331
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/* Copyright (C) 2007-2017  B.A.T.M.A.N. contributors:
 +/* Copyright (C) 2007-2018  B.A.T.M.A.N. contributors:
   *
   * Marek Lindner
   *
@@@ -24,6 -24,7 +24,7 @@@
  #include <linux/debugfs.h>
  #include <linux/errno.h>
  #include <linux/etherdevice.h>
+ #include <linux/eventpoll.h>
  #include <linux/export.h>
  #include <linux/fcntl.h>
  #include <linux/fs.h>
diff --combined net/batman-adv/log.c
index 52d8a4b848c0,cdbe0e5e208b..853773e45f79
--- a/net/batman-adv/log.c
+++ b/net/batman-adv/log.c
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/* Copyright (C) 2010-2017  B.A.T.M.A.N. contributors:
 +/* Copyright (C) 2010-2018  B.A.T.M.A.N. contributors:
   *
   * Marek Lindner
   *
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/compiler.h>
  #include <linux/debugfs.h>
  #include <linux/errno.h>
+ #include <linux/eventpoll.h>
  #include <linux/export.h>
  #include <linux/fcntl.h>
  #include <linux/fs.h>
diff --combined net/batman-adv/multicast.c
index 5615b6abea6f,d70640135e3a..de3a055f7dd8
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/* Copyright (C) 2014-2017  B.A.T.M.A.N. contributors:
 +/* Copyright (C) 2014-2018  B.A.T.M.A.N. contributors:
   *
   * Linus L├╝ssing
   *
@@@ -40,7 -40,6 +40,7 @@@
  #include <linux/list.h>
  #include <linux/lockdep.h>
  #include <linux/netdevice.h>
 +#include <linux/netlink.h>
  #include <linux/printk.h>
  #include <linux/rculist.h>
  #include <linux/rcupdate.h>
@@@ -53,20 -52,14 +53,20 @@@
  #include <linux/types.h>
  #include <linux/workqueue.h>
  #include <net/addrconf.h>
 +#include <net/genetlink.h>
  #include <net/if_inet6.h>
  #include <net/ip.h>
  #include <net/ipv6.h>
 +#include <net/netlink.h>
 +#include <net/sock.h>
  #include <uapi/linux/batadv_packet.h>
 +#include <uapi/linux/batman_adv.h>
  
  #include "hard-interface.h"
  #include "hash.h"
  #include "log.h"
 +#include "netlink.h"
 +#include "soft-interface.h"
  #include "translation-table.h"
  #include "tvlv.h"
  
@@@ -109,36 -102,7 +109,36 @@@ static struct net_device *batadv_mcast_
  }
  
  /**
 + * batadv_mcast_addr_is_ipv4() - check if multicast MAC is IPv4
 + * @addr: the MAC address to check
 + *
 + * Return: True, if MAC address is one reserved for IPv4 multicast, false
 + * otherwise.
 + */
 +static bool batadv_mcast_addr_is_ipv4(const u8 *addr)
 +{
 +	static const u8 prefix[] = {0x01, 0x00, 0x5E};
 +
 +	return memcmp(prefix, addr, sizeof(prefix)) == 0;
 +}
 +
 +/**
 + * batadv_mcast_addr_is_ipv6() - check if multicast MAC is IPv6
 + * @addr: the MAC address to check
 + *
 + * Return: True, if MAC address is one reserved for IPv6 multicast, false
 + * otherwise.
 + */
 +static bool batadv_mcast_addr_is_ipv6(const u8 *addr)
 +{
 +	static const u8 prefix[] = {0x33, 0x33};
 +
 +	return memcmp(prefix, addr, sizeof(prefix)) == 0;
 +}
 +
 +/**
   * batadv_mcast_mla_softif_get() - get softif multicast listeners
 + * @bat_priv: the bat priv with all the soft interface information
   * @dev: the device to collect multicast addresses from
   * @mcast_list: a list to put found addresses into
   *
@@@ -155,12 -119,9 +155,12 @@@
   * Return: -ENOMEM on memory allocation error or the number of
   * items added to the mcast_list otherwise.
   */
 -static int batadv_mcast_mla_softif_get(struct net_device *dev,
 +static int batadv_mcast_mla_softif_get(struct batadv_priv *bat_priv,
 +				       struct net_device *dev,
  				       struct hlist_head *mcast_list)
  {
 +	bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
 +	bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
  	struct net_device *bridge = batadv_mcast_get_bridge(dev);
  	struct netdev_hw_addr *mc_list_entry;
  	struct batadv_hw_addr *new;
@@@ -168,12 -129,6 +168,12 @@@
  
  	netif_addr_lock_bh(bridge ? bridge : dev);
  	netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
 +		if (all_ipv4 && batadv_mcast_addr_is_ipv4(mc_list_entry->addr))
 +			continue;
 +
 +		if (all_ipv6 && batadv_mcast_addr_is_ipv6(mc_list_entry->addr))
 +			continue;
 +
  		new = kmalloc(sizeof(*new), GFP_ATOMIC);
  		if (!new) {
  			ret = -ENOMEM;
@@@ -238,7 -193,6 +238,7 @@@ static void batadv_mcast_mla_br_addr_cp
  
  /**
   * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
 + * @bat_priv: the bat priv with all the soft interface information
   * @dev: a bridge slave whose bridge to collect multicast addresses from
   * @mcast_list: a list to put found addresses into
   *
@@@ -250,13 -204,10 +250,13 @@@
   * Return: -ENOMEM on memory allocation error or the number of
   * items added to the mcast_list otherwise.
   */
 -static int batadv_mcast_mla_bridge_get(struct net_device *dev,
 +static int batadv_mcast_mla_bridge_get(struct batadv_priv *bat_priv,
 +				       struct net_device *dev,
  				       struct hlist_head *mcast_list)
  {
  	struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
 +	bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
 +	bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
  	struct br_ip_list *br_ip_entry, *tmp;
  	struct batadv_hw_addr *new;
  	u8 mcast_addr[ETH_ALEN];
@@@ -270,12 -221,6 +270,12 @@@
  		goto out;
  
  	list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
 +		if (all_ipv4 && br_ip_entry->addr.proto == htons(ETH_P_IP))
 +			continue;
 +
 +		if (all_ipv6 && br_ip_entry->addr.proto == htons(ETH_P_IPV6))
 +			continue;
 +
  		batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
  		if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
  			continue;
@@@ -598,8 -543,8 +598,8 @@@ update
  		bat_priv->mcast.enabled = true;
  	}
  
- 	return !(mcast_data.flags &
- 		 (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6));
+ 	return !(mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV4 &&
+ 		 mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV6);
  }
  
  /**
@@@ -623,11 -568,11 +623,11 @@@ static void __batadv_mcast_mla_update(s
  	if (!batadv_mcast_mla_tvlv_update(bat_priv))
  		goto update;
  
 -	ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
 +	ret = batadv_mcast_mla_softif_get(bat_priv, soft_iface, &mcast_list);
  	if (ret < 0)
  		goto out;
  
 -	ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
 +	ret = batadv_mcast_mla_bridge_get(bat_priv, soft_iface, &mcast_list);
  	if (ret < 0)
  		goto out;
  
@@@ -1341,236 -1286,6 +1341,236 @@@ int batadv_mcast_flags_seq_print_text(s
  #endif
  
  /**
 + * batadv_mcast_mesh_info_put() - put multicast info into a netlink message
 + * @msg: buffer for the message
 + * @bat_priv: the bat priv with all the soft interface information
 + *
 + * Return: 0 or error code.
 + */
 +int batadv_mcast_mesh_info_put(struct sk_buff *msg,
 +			       struct batadv_priv *bat_priv)
 +{
 +	u32 flags = bat_priv->mcast.flags;
 +	u32 flags_priv = BATADV_NO_FLAGS;
 +
 +	if (bat_priv->mcast.bridged) {
 +		flags_priv |= BATADV_MCAST_FLAGS_BRIDGED;
 +
 +		if (bat_priv->mcast.querier_ipv4.exists)
 +			flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS;
 +		if (bat_priv->mcast.querier_ipv6.exists)
 +			flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS;
 +		if (bat_priv->mcast.querier_ipv4.shadowing)
 +			flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING;
 +		if (bat_priv->mcast.querier_ipv6.shadowing)
 +			flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING;
 +	}
 +
 +	if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) ||
 +	    nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv))
 +		return -EMSGSIZE;
 +
 +	return 0;
 +}
 +
 +/**
 + * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table
 + *  to a netlink socket
 + * @msg: buffer for the message
 + * @portid: netlink port
 + * @seq: Sequence number of netlink message
 + * @orig_node: originator to dump the multicast flags of
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
 +			      struct batadv_orig_node *orig_node)
 +{
 +	void *hdr;
 +
 +	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
 +			  NLM_F_MULTI, BATADV_CMD_GET_MCAST_FLAGS);
 +	if (!hdr)
 +		return -ENOBUFS;
 +
 +	if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
 +		    orig_node->orig)) {
 +		genlmsg_cancel(msg, hdr);
 +		return -EMSGSIZE;
 +	}
 +
 +	if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
 +		     &orig_node->capabilities)) {
 +		if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS,
 +				orig_node->mcast_flags)) {
 +			genlmsg_cancel(msg, hdr);
 +			return -EMSGSIZE;
 +		}
 +	}
 +
 +	genlmsg_end(msg, hdr);
 +	return 0;
 +}
 +
 +/**
 + * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags
 + *  table to a netlink socket
 + * @msg: buffer for the message
 + * @portid: netlink port
 + * @seq: Sequence number of netlink message
 + * @head: bucket to dump
 + * @idx_skip: How many entries to skip
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
 +			       struct hlist_head *head, long *idx_skip)
 +{
 +	struct batadv_orig_node *orig_node;
 +	long idx = 0;
 +
 +	rcu_read_lock();
 +	hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
 +		if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
 +			      &orig_node->capa_initialized))
 +			continue;
 +
 +		if (idx < *idx_skip)
 +			goto skip;
 +
 +		if (batadv_mcast_flags_dump_entry(msg, portid, seq,
 +						  orig_node)) {
 +			rcu_read_unlock();
 +			*idx_skip = idx;
 +
 +			return -EMSGSIZE;
 +		}
 +
 +skip:
 +		idx++;
 +	}
 +	rcu_read_unlock();
 +
 +	return 0;
 +}
 +
 +/**
 + * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
 + * @msg: buffer for the message
 + * @portid: netlink port
 + * @seq: Sequence number of netlink message
 + * @bat_priv: the bat priv with all the soft interface information
 + * @bucket: current bucket to dump
 + * @idx: index in current bucket to the next entry to dump
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, u32 seq,
 +			  struct batadv_priv *bat_priv, long *bucket, long *idx)
 +{
 +	struct batadv_hashtable *hash = bat_priv->orig_hash;
 +	long bucket_tmp = *bucket;
 +	struct hlist_head *head;
 +	long idx_tmp = *idx;
 +
 +	while (bucket_tmp < hash->size) {
 +		head = &hash->table[bucket_tmp];
 +
 +		if (batadv_mcast_flags_dump_bucket(msg, portid, seq, head,
 +						   &idx_tmp))
 +			break;
 +
 +		bucket_tmp++;
 +		idx_tmp = 0;
 +	}
 +
 +	*bucket = bucket_tmp;
 +	*idx = idx_tmp;
 +
 +	return msg->len;
 +}
 +
 +/**
 + * batadv_mcast_netlink_get_primary() - get primary interface from netlink
 + *  callback
 + * @cb: netlink callback structure
 + * @primary_if: the primary interface pointer to return the result in
 + *
 + * Return: 0 or error code.
 + */
 +static int
 +batadv_mcast_netlink_get_primary(struct netlink_callback *cb,
 +				 struct batadv_hard_iface **primary_if)
 +{
 +	struct batadv_hard_iface *hard_iface = NULL;
 +	struct net *net = sock_net(cb->skb->sk);
 +	struct net_device *soft_iface;
 +	struct batadv_priv *bat_priv;
 +	int ifindex;
 +	int ret = 0;
 +
 +	ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
 +	if (!ifindex)
 +		return -EINVAL;
 +
 +	soft_iface = dev_get_by_index(net, ifindex);
 +	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
 +		ret = -ENODEV;
 +		goto out;
 +	}
 +
 +	bat_priv = netdev_priv(soft_iface);
 +
 +	hard_iface = batadv_primary_if_get_selected(bat_priv);
 +	if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) {
 +		ret = -ENOENT;
 +		goto out;
 +	}
 +
 +out:
 +	if (soft_iface)
 +		dev_put(soft_iface);
 +
 +	if (!ret && primary_if)
 +		*primary_if = hard_iface;
 +	else
 +		batadv_hardif_put(hard_iface);
 +
 +	return ret;
 +}
 +
 +/**
 + * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
 + * @msg: buffer for the message
 + * @cb: callback structure containing arguments
 + *
 + * Return: message length.
 + */
 +int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)
 +{
 +	struct batadv_hard_iface *primary_if = NULL;
 +	int portid = NETLINK_CB(cb->skb).portid;
 +	struct batadv_priv *bat_priv;
 +	long *bucket = &cb->args[0];
 +	long *idx = &cb->args[1];
 +	int ret;
 +
 +	ret = batadv_mcast_netlink_get_primary(cb, &primary_if);
 +	if (ret)
 +		return ret;
 +
 +	bat_priv = netdev_priv(primary_if->soft_iface);
 +	ret = __batadv_mcast_flags_dump(msg, portid, cb->nlh->nlmsg_seq,
 +					bat_priv, bucket, idx);
 +
 +	batadv_hardif_put(primary_if);
 +	return ret;
 +}
 +
 +/**
   * batadv_mcast_free() - free the multicast optimizations structures
   * @bat_priv: the bat priv with all the soft interface information
   */
diff --combined net/batman-adv/routing.c
index 289df027ecdd,e61dc1293bb5..cc3ed93a6d51
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@@ -1,5 -1,5 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0
 -/* Copyright (C) 2007-2017  B.A.T.M.A.N. contributors:
 +/* Copyright (C) 2007-2018  B.A.T.M.A.N. contributors:
   *
   * Marek Lindner, Simon Wunderlich
   *
@@@ -759,6 -759,7 +759,7 @@@ free_skb
  /**
   * batadv_reroute_unicast_packet() - update the unicast header for re-routing
   * @bat_priv: the bat priv with all the soft interface information
+  * @skb: unicast packet to process
   * @unicast_packet: the unicast header to be updated
   * @dst_addr: the payload destination
   * @vid: VLAN identifier
@@@ -770,7 -771,7 +771,7 @@@
   * Return: true if the packet header has been updated, false otherwise
   */
  static bool
- batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
+ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
  			      struct batadv_unicast_packet *unicast_packet,
  			      u8 *dst_addr, unsigned short vid)
  {
@@@ -799,8 -800,10 +800,10 @@@
  	}
  
  	/* update the packet header */
+ 	skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
  	ether_addr_copy(unicast_packet->dest, orig_addr);
  	unicast_packet->ttvn = orig_ttvn;
+ 	skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
  
  	ret = true;
  out:
@@@ -841,7 -844,7 +844,7 @@@ static bool batadv_check_unicast_ttvn(s
  	 * the packet to
  	 */
  	if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
- 		if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
+ 		if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
  						  ethhdr->h_dest, vid))
  			batadv_dbg_ratelimited(BATADV_DBG_TT,
  					       bat_priv,
@@@ -887,7 -890,7 +890,7 @@@
  	 * destination can possibly be updated and forwarded towards the new
  	 * target host
  	 */
- 	if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
+ 	if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
  					  ethhdr->h_dest, vid)) {
  		batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv,
  				       "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
@@@ -910,12 -913,14 +913,14 @@@
  	if (!primary_if)
  		return false;
  
+ 	/* update the packet header */
+ 	skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
  	ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr);
+ 	unicast_packet->ttvn = curr_ttvn;
+ 	skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
  
  	batadv_hardif_put(primary_if);
  
- 	unicast_packet->ttvn = curr_ttvn;
- 
  	return true;
  }
  
@@@ -968,14 -973,10 +973,10 @@@ int batadv_recv_unicast_packet(struct s
  	struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL;
  	int check, hdr_size = sizeof(*unicast_packet);
  	enum batadv_subtype subtype;
- 	struct ethhdr *ethhdr;
  	int ret = NET_RX_DROP;
  	bool is4addr, is_gw;
  
  	unicast_packet = (struct batadv_unicast_packet *)skb->data;
- 	unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
- 	ethhdr = eth_hdr(skb);
- 
  	is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
  	/* the caller function should have already pulled 2 bytes */
  	if (is4addr)
@@@ -995,12 -996,14 +996,14 @@@
  	if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
  		goto free_skb;
  
+ 	unicast_packet = (struct batadv_unicast_packet *)skb->data;
+ 
  	/* packet for me */
  	if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
  		/* If this is a unicast packet from another backgone gw,
  		 * drop it.
  		 */
- 		orig_addr_gw = ethhdr->h_source;
+ 		orig_addr_gw = eth_hdr(skb)->h_source;
  		orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw);
  		if (orig_node_gw) {
  			is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw,
@@@ -1015,6 -1018,8 +1018,8 @@@
  		}
  
  		if (is4addr) {
+ 			unicast_4addr_packet =
+ 				(struct batadv_unicast_4addr_packet *)skb->data;
  			subtype = unicast_4addr_packet->subtype;
  			batadv_dat_inc_counter(bat_priv, subtype);
  
diff --combined net/core/dev.c
index d8887cc38e7b,12be20535714..f9c28f44286c
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@@ -2378,7 -2378,7 +2378,7 @@@ EXPORT_SYMBOL(netdev_set_num_tc)
  
  /*
   * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
 - * greater then real_num_tx_queues stale skbs on the qdisc must be flushed.
 + * greater than real_num_tx_queues stale skbs on the qdisc must be flushed.
   */
  int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
  {
@@@ -3278,15 -3278,23 +3278,23 @@@ static inline int __dev_xmit_skb(struc
  #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);
+ 	const struct netprio_map *map;
+ 	const struct sock *sk;
+ 	unsigned int prioidx;
  
- 	if (!skb->priority && skb->sk && map) {
- 		unsigned int prioidx =
- 			sock_cgroup_prioidx(&skb->sk->sk_cgrp_data);
+ 	if (skb->priority)
+ 		return;
+ 	map = rcu_dereference_bh(skb->dev->priomap);
+ 	if (!map)
+ 		return;
+ 	sk = skb_to_full_sk(skb);
+ 	if (!sk)
+ 		return;
  
- 		if (prioidx < map->priomap_len)
- 			skb->priority = map->priomap[prioidx];
- 	}
+ 	prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data);
+ 
+ 	if (prioidx < map->priomap_len)
+ 		skb->priority = map->priomap[prioidx];
  }
  #else
  #define skb_update_prio(skb)
@@@ -4351,9 -4359,6 +4359,9 @@@ int netdev_rx_handler_register(struct n
  	if (netdev_is_rx_handler_busy(dev))
  		return -EBUSY;
  
 +	if (dev->priv_flags & IFF_NO_RX_HANDLER)
 +		return -EINVAL;
 +
  	/* Note: rx_handler_data must be set before rx_handler */
  	rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
  	rcu_assign_pointer(dev->rx_handler, rx_handler);
@@@ -7549,19 -7554,6 +7557,19 @@@ static netdev_features_t netdev_fix_fea
  		}
  	}
  
 +	/* LRO/HW-GRO features cannot be combined with RX-FCS */
 +	if (features & NETIF_F_RXFCS) {
 +		if (features & NETIF_F_LRO) {
 +			netdev_dbg(dev, "Dropping LRO feature since RX-FCS is requested.\n");
 +			features &= ~NETIF_F_LRO;
 +		}
 +
 +		if (features & NETIF_F_GRO_HW) {
 +			netdev_dbg(dev, "Dropping HW-GRO feature since RX-FCS is requested.\n");
 +			features &= ~NETIF_F_GRO_HW;
 +		}
 +	}
 +
  	return features;
  }
  
@@@ -8018,8 -8010,7 +8026,8 @@@ int register_netdev(struct net_device *
  {
  	int err;
  
 -	rtnl_lock();
 +	if (rtnl_lock_killable())
 +		return -EINTR;
  	err = register_netdevice(dev);
  	rtnl_unlock();
  	return err;
@@@ -8162,9 -8153,8 +8170,9 @@@ void netdev_run_todo(void
  		BUG_ON(!list_empty(&dev->ptype_specific));
  		WARN_ON(rcu_access_pointer(dev->ip_ptr));
  		WARN_ON(rcu_access_pointer(dev->ip6_ptr));
 +#if IS_ENABLED(CONFIG_DECNET)
  		WARN_ON(dev->dn_ptr);
 -
 +#endif
  		if (dev->priv_destructor)
  			dev->priv_destructor(dev);
  		if (dev->needs_free_netdev)
@@@ -8862,7 -8852,6 +8870,7 @@@ static void __net_exit netdev_exit(stru
  static struct pernet_operations __net_initdata netdev_net_ops = {
  	.init = netdev_init,
  	.exit = netdev_exit,
 +	.async = true,
  };
  
  static void __net_exit default_device_exit(struct net *net)
@@@ -8963,7 -8952,6 +8971,7 @@@ static void __net_exit default_device_e
  static struct pernet_operations __net_initdata default_device_ops = {
  	.exit = default_device_exit,
  	.exit_batch = default_device_exit_batch,
 +	.async = true,
  };
  
  /*
diff --combined net/core/devlink.c
index d03b96f87c25,effd4848c2b4..9236e421bd62
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@@ -1798,7 -1798,7 +1798,7 @@@ send_done
  	if (!nlh) {
  		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  		if (err)
- 			goto err_skb_send_alloc;
+ 			return err;
  		goto send_done;
  	}
  
@@@ -1807,7 -1807,6 +1807,6 @@@
  nla_put_failure:
  	err = -EMSGSIZE;
  err_table_put:
- err_skb_send_alloc:
  	genlmsg_cancel(skb, hdr);
  	nlmsg_free(skb);
  	return err;
@@@ -2073,7 -2072,7 +2072,7 @@@ static int devlink_dpipe_entries_fill(s
  					     table->counters_enabled,
  					     &dump_ctx);
  	if (err)
- 		goto err_entries_dump;
+ 		return err;
  
  send_done:
  	nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
@@@ -2081,16 -2080,10 +2080,10 @@@
  	if (!nlh) {
  		err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
  		if (err)
- 			goto err_skb_send_alloc;
+ 			return err;
  		goto send_done;
  	}
  	return genlmsg_reply(dump_ctx.skb, info);
- 
- err_entries_dump:
- err_skb_send_alloc:
- 	genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr);
- 	nlmsg_free(dump_ctx.skb);
- 	return err;
  }
  
  static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
@@@ -2229,7 -2222,7 +2222,7 @@@ send_done
  	if (!nlh) {
  		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
  		if (err)
- 			goto err_skb_send_alloc;
+ 			return err;
  		goto send_done;
  	}
  	return genlmsg_reply(skb, info);
@@@ -2237,7 -2230,6 +2230,6 @@@
  nla_put_failure:
  	err = -EMSGSIZE;
  err_table_put:
- err_skb_send_alloc:
  	genlmsg_cancel(skb, hdr);
  	nlmsg_free(skb);
  	return err;
@@@ -2339,32 -2331,6 +2331,32 @@@ out
  	resource->size_valid = size_valid;
  }
  
 +static int
 +devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
 +			       struct netlink_ext_ack *extack)
 +{
 +	u64 reminder;
 +	int err = 0;
 +
 +	if (size > resource->size_params.size_max) {
 +		NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
 +		err = -EINVAL;
 +	}
 +
 +	if (size < resource->size_params.size_min) {
 +		NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
 +		err = -EINVAL;
 +	}
 +
 +	div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
 +	if (reminder) {
 +		NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
 +		err = -EINVAL;
 +	}
 +
 +	return err;
 +}
 +
  static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
  				       struct genl_info *info)
  {
@@@ -2383,8 -2349,12 +2375,8 @@@
  	if (!resource)
  		return -EINVAL;
  
 -	if (!resource->resource_ops->size_validate)
 -		return -EINVAL;
 -
  	size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
 -	err = resource->resource_ops->size_validate(devlink, size,
 -						    info->extack);
 +	err = devlink_resource_validate_size(resource, size, info->extack);
  	if (err)
  		return err;
  
@@@ -2744,22 -2714,22 +2736,22 @@@ static const struct genl_ops devlink_nl
  		.cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
  		.doit = devlink_nl_cmd_dpipe_table_get,
  		.policy = devlink_nl_policy,
 -		.flags = GENL_ADMIN_PERM,
  		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
 +		/* can be retrieved by unprivileged users */
  	},
  	{
  		.cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
  		.doit = devlink_nl_cmd_dpipe_entries_get,
  		.policy = devlink_nl_policy,
 -		.flags = GENL_ADMIN_PERM,
  		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
 +		/* can be retrieved by unprivileged users */
  	},
  	{
  		.cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
  		.doit = devlink_nl_cmd_dpipe_headers_get,
  		.policy = devlink_nl_policy,
 -		.flags = GENL_ADMIN_PERM,
  		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
 +		/* can be retrieved by unprivileged users */
  	},
  	{
  		.cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
@@@ -2779,8 -2749,8 +2771,8 @@@
  		.cmd = DEVLINK_CMD_RESOURCE_DUMP,
  		.doit = devlink_nl_cmd_resource_dump,
  		.policy = devlink_nl_policy,
 -		.flags = GENL_ADMIN_PERM,
  		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
 +		/* can be retrieved by unprivileged users */
  	},
  	{
  		.cmd = DEVLINK_CMD_RELOAD,
@@@ -3174,6 -3144,7 +3166,6 @@@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_u
   */
  int devlink_resource_register(struct devlink *devlink,
  			      const char *resource_name,
 -			      bool top_hierarchy,
  			      u64 resource_size,
  			      u64 resource_id,
  			      u64 parent_resource_id,
@@@ -3182,11 -3153,8 +3174,11 @@@
  {
  	struct devlink_resource *resource;
  	struct list_head *resource_list;
 +	bool top_hierarchy;
  	int err = 0;
  
 +	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
 +
  	mutex_lock(&devlink->lock);
  	resource = devlink_resource_find(devlink, NULL, resource_id);
  	if (resource) {
diff --combined net/core/filter.c
index c86f03fd9ea5,48aa7c7320db..00c711c5f1a2
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@@ -1890,202 -1890,6 +1890,202 @@@ static const struct bpf_func_proto bpf_
  	.arg4_type      = ARG_ANYTHING,
  };
  
 +BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg_buff *, msg,
 +	   struct bpf_map *, map, u32, key, u64, flags)
 +{
 +	/* If user passes invalid input drop the packet. */
 +	if (unlikely(flags))
 +		return SK_DROP;
 +
 +	msg->key = key;
 +	msg->flags = flags;
 +	msg->map = map;
 +
 +	return SK_PASS;
 +}
 +
 +struct sock *do_msg_redirect_map(struct sk_msg_buff *msg)
 +{
 +	struct sock *sk = NULL;
 +
 +	if (msg->map) {
 +		sk = __sock_map_lookup_elem(msg->map, msg->key);
 +
 +		msg->key = 0;
 +		msg->map = NULL;
 +	}
 +
 +	return sk;
 +}
 +
 +static const struct bpf_func_proto bpf_msg_redirect_map_proto = {
 +	.func           = bpf_msg_redirect_map,
 +	.gpl_only       = false,
 +	.ret_type       = RET_INTEGER,
 +	.arg1_type	= ARG_PTR_TO_CTX,
 +	.arg2_type      = ARG_CONST_MAP_PTR,
 +	.arg3_type      = ARG_ANYTHING,
 +	.arg4_type      = ARG_ANYTHING,
 +};
 +
 +BPF_CALL_2(bpf_msg_apply_bytes, struct sk_msg_buff *, msg, u32, bytes)
 +{
 +	msg->apply_bytes = bytes;
 +	return 0;
 +}
 +
 +static const struct bpf_func_proto bpf_msg_apply_bytes_proto = {
 +	.func           = bpf_msg_apply_bytes,
 +	.gpl_only       = false,
 +	.ret_type       = RET_INTEGER,
 +	.arg1_type	= ARG_PTR_TO_CTX,
 +	.arg2_type      = ARG_ANYTHING,
 +};
 +
 +BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg_buff *, msg, u32, bytes)
 +{
 +	msg->cork_bytes = bytes;
 +	return 0;
 +}
 +
 +static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
 +	.func           = bpf_msg_cork_bytes,
 +	.gpl_only       = false,
 +	.ret_type       = RET_INTEGER,
 +	.arg1_type	= ARG_PTR_TO_CTX,
 +	.arg2_type      = ARG_ANYTHING,
 +};
 +
 +BPF_CALL_4(bpf_msg_pull_data,
 +	   struct sk_msg_buff *, msg, u32, start, u32, end, u64, flags)
 +{
 +	unsigned int len = 0, offset = 0, copy = 0;
 +	struct scatterlist *sg = msg->sg_data;
 +	int first_sg, last_sg, i, shift;
 +	unsigned char *p, *to, *from;
 +	int bytes = end - start;
 +	struct page *page;
 +
 +	if (unlikely(flags || end <= start))
 +		return -EINVAL;
 +
 +	/* First find the starting scatterlist element */
 +	i = msg->sg_start;
 +	do {
 +		len = sg[i].length;
 +		offset += len;
 +		if (start < offset + len)
 +			break;
 +		i++;
 +		if (i == MAX_SKB_FRAGS)
 +			i = 0;
 +	} while (i != msg->sg_end);
 +
 +	if (unlikely(start >= offset + len))
 +		return -EINVAL;
 +
 +	if (!msg->sg_copy[i] && bytes <= len)
 +		goto out;
 +
 +	first_sg = i;
 +
 +	/* At this point we need to linearize multiple scatterlist
 +	 * elements or a single shared page. Either way we need to
 +	 * copy into a linear buffer exclusively owned by BPF. Then
 +	 * place the buffer in the scatterlist and fixup the original
 +	 * entries by removing the entries now in the linear buffer
 +	 * and shifting the remaining entries. For now we do not try
 +	 * to copy partial entries to avoid complexity of running out
 +	 * of sg_entry slots. The downside is reading a single byte
 +	 * will copy the entire sg entry.
 +	 */
 +	do {
 +		copy += sg[i].length;
 +		i++;
 +		if (i == MAX_SKB_FRAGS)
 +			i = 0;
 +		if (bytes < copy)
 +			break;
 +	} while (i != msg->sg_end);
 +	last_sg = i;
 +
 +	if (unlikely(copy < end - start))
 +		return -EINVAL;
 +
 +	page = alloc_pages(__GFP_NOWARN | GFP_ATOMIC, get_order(copy));
 +	if (unlikely(!page))
 +		return -ENOMEM;
 +	p = page_address(page);
 +	offset = 0;
 +
 +	i = first_sg;
 +	do {
 +		from = sg_virt(&sg[i]);
 +		len = sg[i].length;
 +		to = p + offset;
 +
 +		memcpy(to, from, len);
 +		offset += len;
 +		sg[i].length = 0;
 +		put_page(sg_page(&sg[i]));
 +
 +		i++;
 +		if (i == MAX_SKB_FRAGS)
 +			i = 0;
 +	} while (i != last_sg);
 +
 +	sg[first_sg].length = copy;
 +	sg_set_page(&sg[first_sg], page, copy, 0);
 +
 +	/* To repair sg ring we need to shift entries. If we only
 +	 * had a single entry though we can just replace it and
 +	 * be done. Otherwise walk the ring and shift the entries.
 +	 */
 +	shift = last_sg - first_sg - 1;
 +	if (!shift)
 +		goto out;
 +
 +	i = first_sg + 1;
 +	do {
 +		int move_from;
 +
 +		if (i + shift >= MAX_SKB_FRAGS)
 +			move_from = i + shift - MAX_SKB_FRAGS;
 +		else
 +			move_from = i + shift;
 +
 +		if (move_from == msg->sg_end)
 +			break;
 +
 +		sg[i] = sg[move_from];
 +		sg[move_from].length = 0;
 +		sg[move_from].page_link = 0;
 +		sg[move_from].offset = 0;
 +
 +		i++;
 +		if (i == MAX_SKB_FRAGS)
 +			i = 0;
 +	} while (1);
 +	msg->sg_end -= shift;
 +	if (msg->sg_end < 0)
 +		msg->sg_end += MAX_SKB_FRAGS;
 +out:
 +	msg->data = sg_virt(&sg[i]) + start - offset;
 +	msg->data_end = msg->data + bytes;
 +
 +	return 0;
 +}
 +
 +static const struct bpf_func_proto bpf_msg_pull_data_proto = {
 +	.func		= bpf_msg_pull_data,
 +	.gpl_only	= false,
 +	.ret_type	= RET_INTEGER,
 +	.arg1_type	= ARG_PTR_TO_CTX,
 +	.arg2_type	= ARG_ANYTHING,
 +	.arg3_type	= ARG_ANYTHING,
 +	.arg4_type	= ARG_ANYTHING,
 +};
 +
  BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb)
  {
  	return task_get_classid(skb);
@@@ -2283,6 -2087,10 +2283,10 @@@ static int bpf_skb_proto_4_to_6(struct 
  	u32 off = skb_mac_header_len(skb);
  	int ret;
  
+ 	/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+ 	if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+ 		return -ENOTSUPP;
+ 
  	ret = skb_cow(skb, len_diff);
  	if (unlikely(ret < 0))
  		return ret;
@@@ -2292,19 -2100,21 +2296,21 @@@
  		return ret;
  
  	if (skb_is_gso(skb)) {
+ 		struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 
  		/* SKB_GSO_TCPV4 needs to be changed into
  		 * SKB_GSO_TCPV6.
  		 */
- 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
- 			skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV4;
- 			skb_shinfo(skb)->gso_type |=  SKB_GSO_TCPV6;
+ 		if (shinfo->gso_type & SKB_GSO_TCPV4) {
+ 			shinfo->gso_type &= ~SKB_GSO_TCPV4;
+ 			shinfo->gso_type |=  SKB_GSO_TCPV6;
  		}
  
  		/* Due to IPv6 header, MSS needs to be downgraded. */
- 		skb_shinfo(skb)->gso_size -= len_diff;
+ 		skb_decrease_gso_size(shinfo, len_diff);
  		/* Header must be checked, and gso_segs recomputed. */
- 		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
- 		skb_shinfo(skb)->gso_segs = 0;
+ 		shinfo->gso_type |= SKB_GSO_DODGY;
+ 		shinfo->gso_segs = 0;
  	}
  
  	skb->protocol = htons(ETH_P_IPV6);
@@@ -2319,6 -2129,10 +2325,10 @@@ static int bpf_skb_proto_6_to_4(struct 
  	u32 off = skb_mac_header_len(skb);
  	int ret;
  
+ 	/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+ 	if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+ 		return -ENOTSUPP;
+ 
  	ret = skb_unclone(skb, GFP_ATOMIC);
  	if (unlikely(ret < 0))
  		return ret;
@@@ -2328,19 -2142,21 +2338,21 @@@
  		return ret;
  
  	if (skb_is_gso(skb)) {
+ 		struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 
  		/* SKB_GSO_TCPV6 needs to be changed into
  		 * SKB_GSO_TCPV4.
  		 */
- 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
- 			skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV6;
- 			skb_shinfo(skb)->gso_type |=  SKB_GSO_TCPV4;
+ 		if (shinfo->gso_type & SKB_GSO_TCPV6) {
+ 			shinfo->gso_type &= ~SKB_GSO_TCPV6;
+ 			shinfo->gso_type |=  SKB_GSO_TCPV4;
  		}
  
  		/* Due to IPv4 header, MSS can be upgraded. */
- 		skb_shinfo(skb)->gso_size += len_diff;
+ 		skb_increase_gso_size(shinfo, len_diff);
  		/* Header must be checked, and gso_segs recomputed. */
- 		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
- 		skb_shinfo(skb)->gso_segs = 0;
+ 		shinfo->gso_type |= SKB_GSO_DODGY;
+ 		shinfo->gso_segs = 0;
  	}
  
  	skb->protocol = htons(ETH_P_IP);
@@@ -2439,6 -2255,10 +2451,10 @@@ static int bpf_skb_net_grow(struct sk_b
  	u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
  	int ret;
  
+ 	/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+ 	if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+ 		return -ENOTSUPP;
+ 
  	ret = skb_cow(skb, len_diff);
  	if (unlikely(ret < 0))
  		return ret;
@@@ -2448,11 -2268,13 +2464,13 @@@
  		return ret;
  
  	if (skb_is_gso(skb)) {
+ 		struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 
  		/* Due to header grow, MSS needs to be downgraded. */
- 		skb_shinfo(skb)->gso_size -= len_diff;
+ 		skb_decrease_gso_size(shinfo, len_diff);
  		/* Header must be checked, and gso_segs recomputed. */
- 		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
- 		skb_shinfo(skb)->gso_segs = 0;
+ 		shinfo->gso_type |= SKB_GSO_DODGY;
+ 		shinfo->gso_segs = 0;
  	}
  
  	return 0;
@@@ -2463,6 -2285,10 +2481,10 @@@ static int bpf_skb_net_shrink(struct sk
  	u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
  	int ret;
  
+ 	/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+ 	if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+ 		return -ENOTSUPP;
+ 
  	ret = skb_unclone(skb, GFP_ATOMIC);
  	if (unlikely(ret < 0))
  		return ret;
@@@ -2472,11 -2298,13 +2494,13 @@@
  		return ret;
  
  	if (skb_is_gso(skb)) {
+ 		struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 
  		/* Due to header shrink, MSS can be upgraded. */
- 		skb_shinfo(skb)->gso_size += len_diff;
+ 		skb_increase_gso_size(shinfo, len_diff);
  		/* Header must be checked, and gso_segs recomputed. */
- 		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
- 		skb_shinfo(skb)->gso_segs = 0;
+ 		shinfo->gso_type |= SKB_GSO_DODGY;
+ 		shinfo->gso_segs = 0;
  	}
  
  	return 0;
@@@ -3027,8 -2855,7 +3051,8 @@@ bool bpf_helper_changes_pkt_data(void *
  	    func == bpf_l3_csum_replace ||
  	    func == bpf_l4_csum_replace ||
  	    func == bpf_xdp_adjust_head ||
 -	    func == bpf_xdp_adjust_meta)
 +	    func == bpf_xdp_adjust_meta ||
 +	    func == bpf_msg_pull_data)
  		return true;
  
  	return false;
@@@ -3188,7 -3015,7 +3212,7 @@@ BPF_CALL_4(bpf_skb_set_tunnel_key, stru
  	struct ip_tunnel_info *info;
  
  	if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
 -			       BPF_F_DONT_FRAGMENT)))
 +			       BPF_F_DONT_FRAGMENT | BPF_F_SEQ_NUMBER)))
  		return -EINVAL;
  	if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
  		switch (size) {
@@@ -3222,8 -3049,6 +3246,8 @@@
  		info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
  	if (flags & BPF_F_ZERO_CSUM_TX)
  		info->key.tun_flags &= ~TUNNEL_CSUM;
 +	if (flags & BPF_F_SEQ_NUMBER)
 +		info->key.tun_flags |= TUNNEL_SEQ;
  
  	info->key.tun_id = cpu_to_be64(from->tunnel_id);
  	info->key.tos = from->tunnel_tos;
@@@ -3788,22 -3613,6 +3812,22 @@@ static const struct bpf_func_proto 
  	}
  }
  
 +static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id)
 +{
 +	switch (func_id) {
 +	case BPF_FUNC_msg_redirect_map:
 +		return &bpf_msg_redirect_map_proto;
 +	case BPF_FUNC_msg_apply_bytes:
 +		return &bpf_msg_apply_bytes_proto;
 +	case BPF_FUNC_msg_cork_bytes:
 +		return &bpf_msg_cork_bytes_proto;
 +	case BPF_FUNC_msg_pull_data:
 +		return &bpf_msg_pull_data_proto;
 +	default:
 +		return bpf_base_func_proto(func_id);
 +	}
 +}
 +
  static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id)
  {
  	switch (func_id) {
@@@ -4193,32 -4002,6 +4217,32 @@@ static bool sk_skb_is_valid_access(int 
  	return bpf_skb_is_valid_access(off, size, type, info);
  }
  
 +static bool sk_msg_is_valid_access(int off, int size,
 +				   enum bpf_access_type type,
 +				   struct bpf_insn_access_aux *info)
 +{
 +	if (type == BPF_WRITE)
 +		return false;
 +
 +	switch (off) {
 +	case offsetof(struct sk_msg_md, data):
 +		info->reg_type = PTR_TO_PACKET;
 +		break;
 +	case offsetof(struct sk_msg_md, data_end):
 +		info->reg_type = PTR_TO_PACKET_END;
 +		break;
 +	}
 +
 +	if (off < 0 || off >= sizeof(struct sk_msg_md))
 +		return false;
 +	if (off % size != 0)
 +		return false;
 +	if (size != sizeof(__u64))
 +		return false;
 +
 +	return true;
 +}
 +
  static u32 bpf_convert_ctx_access(enum bpf_access_type type,
  				  const struct bpf_insn *si,
  				  struct bpf_insn *insn_buf,
@@@ -5017,29 -4800,6 +5041,29 @@@ static u32 sk_skb_convert_ctx_access(en
  	return insn - insn_buf;
  }
  
 +static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
 +				     const struct bpf_insn *si,
 +				     struct bpf_insn *insn_buf,
 +				     struct bpf_prog *prog, u32 *target_size)
 +{
 +	struct bpf_insn *insn = insn_buf;
 +
 +	switch (si->off) {
 +	case offsetof(struct sk_msg_md, data):
 +		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_buff, data),
 +				      si->dst_reg, si->src_reg,
 +				      offsetof(struct sk_msg_buff, data));
 +		break;
 +	case offsetof(struct sk_msg_md, data_end):
 +		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_buff, data_end),
 +				      si->dst_reg, si->src_reg,
 +				      offsetof(struct sk_msg_buff, data_end));
 +		break;
 +	}
 +
 +	return insn - insn_buf;
 +}
 +
  const struct bpf_verifier_ops sk_filter_verifier_ops = {
  	.get_func_proto		= sk_filter_func_proto,
  	.is_valid_access	= sk_filter_is_valid_access,
@@@ -5130,15 -4890,6 +5154,15 @@@ const struct bpf_verifier_ops sk_skb_ve
  const struct bpf_prog_ops sk_skb_prog_ops = {
  };
  
 +const struct bpf_verifier_ops sk_msg_verifier_ops = {
 +	.get_func_proto		= sk_msg_func_proto,
 +	.is_valid_access	= sk_msg_is_valid_access,
 +	.convert_ctx_access	= sk_msg_convert_ctx_access,
 +};
 +
 +const struct bpf_prog_ops sk_msg_prog_ops = {
 +};
 +
  int sk_detach_filter(struct sock *sk)
  {
  	int ret = -ENOENT;
diff --combined net/core/skbuff.c
index 715c13495ba6,1e7acdc30732..46cb22215ff4
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@@ -77,8 -77,8 +77,8 @@@
  #include <linux/capability.h>
  #include <linux/user_namespace.h>
  
 -struct kmem_cache *skbuff_head_cache __read_mostly;
 -static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 +struct kmem_cache *skbuff_head_cache __ro_after_init;
 +static struct kmem_cache *skbuff_fclone_cache __ro_after_init;
  int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
  EXPORT_SYMBOL(sysctl_max_skb_frags);
  
@@@ -890,7 -890,7 +890,7 @@@ struct sk_buff *skb_morph(struct sk_buf
  }
  EXPORT_SYMBOL_GPL(skb_morph);
  
 -static int mm_account_pinned_pages(struct mmpin *mmp, size_t size)
 +int mm_account_pinned_pages(struct mmpin *mmp, size_t size)
  {
  	unsigned long max_pg, num_pg, new_pg, old_pg;
  	struct user_struct *user;
@@@ -919,16 -919,14 +919,16 @@@
  
  	return 0;
  }
 +EXPORT_SYMBOL_GPL(mm_account_pinned_pages);
  
 -static void mm_unaccount_pinned_pages(struct mmpin *mmp)
 +void mm_unaccount_pinned_pages(struct mmpin *mmp)
  {
  	if (mmp->user) {
  		atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm);
  		free_uid(mmp->user);
  	}
  }
 +EXPORT_SYMBOL_GPL(mm_unaccount_pinned_pages);
  
  struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
  {
@@@ -4181,7 -4179,7 +4181,7 @@@ int sock_queue_err_skb(struct sock *sk
  
  	skb_queue_tail(&sk->sk_error_queue, skb);
  	if (!sock_flag(sk, SOCK_DEAD))
- 		sk->sk_data_ready(sk);
+ 		sk->sk_error_report(sk);
  	return 0;
  }
  EXPORT_SYMBOL(sock_queue_err_skb);
@@@ -4906,7 -4904,7 +4906,7 @@@ static unsigned int skb_gso_transport_s
  			thlen += inner_tcp_hdrlen(skb);
  	} else if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
  		thlen = tcp_hdrlen(skb);
- 	} else if (unlikely(shinfo->gso_type & SKB_GSO_SCTP)) {
+ 	} else if (unlikely(skb_is_gso_sctp(skb))) {
  		thlen = sizeof(struct sctphdr);
  	}
  	/* UFO sets gso_size to the size of the fragmentation
@@@ -5022,13 -5020,16 +5022,16 @@@ EXPORT_SYMBOL_GPL(skb_gso_validate_mac_
  
  static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
  {
+ 	int mac_len;
+ 
  	if (skb_cow(skb, skb_headroom(skb)) < 0) {
  		kfree_skb(skb);
  		return NULL;
  	}
  
- 	memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
- 		2 * ETH_ALEN);
+ 	mac_len = skb->data - skb_mac_header(skb);
+ 	memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+ 		mac_len - VLAN_HLEN - ETH_TLEN);
  	skb->mac_header += VLAN_HLEN;
  	return skb;
  }
diff --combined net/core/sock.c
index f704324d1219,85b0b64e7f9d..e689496dfd8a
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@@ -1049,18 -1049,16 +1049,18 @@@ set_rcvbuf
  		break;
  
  	case SO_ZEROCOPY:
 -		if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
 +		if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6) {
 +			if (sk->sk_protocol != IPPROTO_TCP)
 +				ret = -ENOTSUPP;
 +		} else if (sk->sk_family != PF_RDS) {
  			ret = -ENOTSUPP;
 -		else if (sk->sk_protocol != IPPROTO_TCP)
 -			ret = -ENOTSUPP;
 -		else if (sk->sk_state != TCP_CLOSE)
 -			ret = -EBUSY;
 -		else if (val < 0 || val > 1)
 -			ret = -EINVAL;
 -		else
 -			sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
 +		}
 +		if (!ret) {
 +			if (val < 0 || val > 1)
 +				ret = -EINVAL;
 +			else
 +				sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
 +		}
  		break;
  
  	default:
@@@ -1276,8 -1274,7 +1276,8 @@@ int sock_getsockopt(struct socket *sock
  	{
  		char address[128];
  
 -		if (sock->ops->getname(sock, (struct sockaddr *)address, &lv, 2))
 +		lv = sock->ops->getname(sock, (struct sockaddr *)address, 2);
 +		if (lv < 0)
  			return -ENOTCONN;
  		if (lv < len)
  			return -EINVAL;
@@@ -1776,7 -1773,7 +1776,7 @@@ void sk_setup_caps(struct sock *sk, str
  	u32 max_segs = 1;
  
  	sk_dst_set(sk, dst);
 -	sk->sk_route_caps = dst->dev->features;
 +	sk->sk_route_caps = dst->dev->features | sk->sk_route_forced_caps;
  	if (sk->sk_route_caps & NETIF_F_GSO)
  		sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
  	sk->sk_route_caps &= ~sk->sk_route_nocaps;
@@@ -2237,67 -2234,6 +2237,67 @@@ bool sk_page_frag_refill(struct sock *s
  }
  EXPORT_SYMBOL(sk_page_frag_refill);
  
 +int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
 +		int sg_start, int *sg_curr_index, unsigned int *sg_curr_size,
 +		int first_coalesce)
 +{
 +	int sg_curr = *sg_curr_index, use = 0, rc = 0;
 +	unsigned int size = *sg_curr_size;
 +	struct page_frag *pfrag;
 +	struct scatterlist *sge;
 +
 +	len -= size;
 +	pfrag = sk_page_frag(sk);
 +
 +	while (len > 0) {
 +		unsigned int orig_offset;
 +
 +		if (!sk_page_frag_refill(sk, pfrag)) {
 +			rc = -ENOMEM;
 +			goto out;
 +		}
 +
 +		use = min_t(int, len, pfrag->size - pfrag->offset);
 +
 +		if (!sk_wmem_schedule(sk, use)) {
 +			rc = -ENOMEM;
 +			goto out;
 +		}
 +
 +		sk_mem_charge(sk, use);
 +		size += use;
 +		orig_offset = pfrag->offset;
 +		pfrag->offset += use;
 +
 +		sge = sg + sg_curr - 1;
 +		if (sg_curr > first_coalesce && sg_page(sg) == pfrag->page &&
 +		    sg->offset + sg->length == orig_offset) {
 +			sg->length += use;
 +		} else {
 +			sge = sg + sg_curr;
 +			sg_unmark_end(sge);
 +			sg_set_page(sge, pfrag->page, use, orig_offset);
 +			get_page(pfrag->page);
 +			sg_curr++;
 +
 +			if (sg_curr == MAX_SKB_FRAGS)
 +				sg_curr = 0;
 +
 +			if (sg_curr == sg_start) {
 +				rc = -ENOSPC;
 +				break;
 +			}
 +		}
 +
 +		len -= use;
 +	}
 +out:
 +	*sg_curr_size = size;
 +	*sg_curr_index = sg_curr;
 +	return rc;
 +}
 +EXPORT_SYMBOL(sk_alloc_sg);
 +
  static void __lock_sock(struct sock *sk)
  	__releases(&sk->sk_lock.slock)
  	__acquires(&sk->sk_lock.slock)
@@@ -2561,7 -2497,7 +2561,7 @@@ int sock_no_accept(struct socket *sock
  EXPORT_SYMBOL(sock_no_accept);
  
  int sock_no_getname(struct socket *sock, struct sockaddr *saddr,
 -		    int *len, int peer)
 +		    int peer)
  {
  	return -EOPNOTSUPP;
  }
@@@ -3175,7 -3111,6 +3175,7 @@@ static void __net_exit sock_inuse_exit_
  static struct pernet_operations net_inuse_ops = {
  	.init = sock_inuse_init_net,
  	.exit = sock_inuse_exit_net,
 +	.async = true,
  };
  
  static __init int net_inuse_init(void)
@@@ -3326,6 -3261,27 +3326,27 @@@ void proto_unregister(struct proto *pro
  }
  EXPORT_SYMBOL(proto_unregister);
  
+ int sock_load_diag_module(int family, int protocol)
+ {
+ 	if (!protocol) {
+ 		if (!sock_is_registered(family))
+ 			return -ENOENT;
+ 
+ 		return request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+ 				      NETLINK_SOCK_DIAG, family);
+ 	}
+ 
+ #ifdef CONFIG_INET
+ 	if (family == AF_INET &&
+ 	    !rcu_access_pointer(inet_protos[protocol]))
+ 		return -ENOENT;
+ #endif
+ 
+ 	return request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
+ 			      NETLINK_SOCK_DIAG, family, protocol);
+ }
+ EXPORT_SYMBOL(sock_load_diag_module);
+ 
  #ifdef CONFIG_PROC_FS
  static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
  	__acquires(proto_list_mutex)
@@@ -3449,7 -3405,6 +3470,7 @@@ static __net_exit void proto_exit_net(s
  static __net_initdata struct pernet_operations proto_net_ops = {
  	.init = proto_init_net,
  	.exit = proto_exit_net,
 +	.async = true,
  };
  
  static int __init proto_init(void)
diff --combined net/core/sock_diag.c
index aee5642affd9,c37b5be7c5e4..a3392a8f9276
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@@ -220,8 -220,7 +220,7 @@@ static int __sock_diag_cmd(struct sk_bu
  		return -EINVAL;
  
  	if (sock_diag_handlers[req->sdiag_family] == NULL)
- 		request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- 				NETLINK_SOCK_DIAG, req->sdiag_family);
+ 		sock_load_diag_module(req->sdiag_family, 0);
  
  	mutex_lock(&sock_diag_table_mutex);
  	hndl = sock_diag_handlers[req->sdiag_family];
@@@ -247,8 -246,7 +246,7 @@@ static int sock_diag_rcv_msg(struct sk_
  	case TCPDIAG_GETSOCK:
  	case DCCPDIAG_GETSOCK:
  		if (inet_rcv_compat == NULL)
- 			request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- 					NETLINK_SOCK_DIAG, AF_INET);
+ 			sock_load_diag_module(AF_INET, 0);
  
  		mutex_lock(&sock_diag_table_mutex);
  		if (inet_rcv_compat != NULL)
@@@ -281,14 -279,12 +279,12 @@@ static int sock_diag_bind(struct net *n
  	case SKNLGRP_INET_TCP_DESTROY:
  	case SKNLGRP_INET_UDP_DESTROY:
  		if (!sock_diag_handlers[AF_INET])
- 			request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- 				       NETLINK_SOCK_DIAG, AF_INET);
+ 			sock_load_diag_module(AF_INET, 0);
  		break;
  	case SKNLGRP_INET6_TCP_DESTROY:
  	case SKNLGRP_INET6_UDP_DESTROY:
  		if (!sock_diag_handlers[AF_INET6])
- 			request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- 				       NETLINK_SOCK_DIAG, AF_INET6);
+ 			sock_load_diag_module(AF_INET6, 0);
  		break;
  	}
  	return 0;
@@@ -328,7 -324,6 +324,7 @@@ static void __net_exit diag_net_exit(st
  static struct pernet_operations diag_net_ops = {
  	.init = diag_net_init,
  	.exit = diag_net_exit,
 +	.async = true,
  };
  
  static int __init sock_diag_init(void)
diff --combined net/ieee802154/6lowpan/core.c
index e4f305320519,e9f0489e4229..275449b0d633
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@@ -104,7 -104,6 +104,7 @@@ static void lowpan_setup(struct net_dev
  	/* We need an ipv6hdr as minimum len when calling xmit */
  	ldev->hard_header_len	= sizeof(struct ipv6hdr);
  	ldev->flags		= IFF_BROADCAST | IFF_MULTICAST;
 +	ldev->priv_flags	|= IFF_NO_QUEUE;
  
  	ldev->netdev_ops	= &lowpan_netdev_ops;
  	ldev->header_ops	= &lowpan_header_ops;
@@@ -207,9 -206,13 +207,13 @@@ static inline void lowpan_netlink_fini(
  static int lowpan_device_event(struct notifier_block *unused,
  			       unsigned long event, void *ptr)
  {
- 	struct net_device *wdev = netdev_notifier_info_to_dev(ptr);
+ 	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+ 	struct wpan_dev *wpan_dev;
  
- 	if (wdev->type != ARPHRD_IEEE802154)
+ 	if (ndev->type != ARPHRD_IEEE802154)
+ 		return NOTIFY_DONE;
+ 	wpan_dev = ndev->ieee802154_ptr;
+ 	if (!wpan_dev)
  		return NOTIFY_DONE;
  
  	switch (event) {
@@@ -218,8 -221,8 +222,8 @@@
  		 * also delete possible lowpan interfaces which belongs
  		 * to the wpan interface.
  		 */
- 		if (wdev->ieee802154_ptr->lowpan_dev)
- 			lowpan_dellink(wdev->ieee802154_ptr->lowpan_dev, NULL);
+ 		if (wpan_dev->lowpan_dev)
+ 			lowpan_dellink(wpan_dev->lowpan_dev, NULL);
  		break;
  	default:
  		return NOTIFY_DONE;
diff --combined net/ipv4/route.c
index e74ee837b300,299e247b2032..4ac5728689f5
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@@ -418,7 -418,6 +418,7 @@@ static void __net_exit ip_rt_do_proc_ex
  static struct pernet_operations ip_rt_proc_ops __net_initdata =  {
  	.init = ip_rt_do_proc_init,
  	.exit = ip_rt_do_proc_exit,
 +	.async = true,
  };
  
  static int __init ip_rt_proc_init(void)
@@@ -635,6 -634,7 +635,7 @@@ static inline u32 fnhe_hashfun(__be32 d
  static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe)
  {
  	rt->rt_pmtu = fnhe->fnhe_pmtu;
+ 	rt->rt_mtu_locked = fnhe->fnhe_mtu_locked;
  	rt->dst.expires = fnhe->fnhe_expires;
  
  	if (fnhe->fnhe_gw) {
@@@ -645,7 -645,7 +646,7 @@@
  }
  
  static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
- 				  u32 pmtu, unsigned long expires)
+ 				  u32 pmtu, bool lock, unsigned long expires)
  {
  	struct fnhe_hash_bucket *hash;
  	struct fib_nh_exception *fnhe;
@@@ -682,8 -682,10 +683,10 @@@
  			fnhe->fnhe_genid = genid;
  		if (gw)
  			fnhe->fnhe_gw = gw;
- 		if (pmtu)
+ 		if (pmtu) {
  			fnhe->fnhe_pmtu = pmtu;
+ 			fnhe->fnhe_mtu_locked = lock;
+ 		}
  		fnhe->fnhe_expires = max(1UL, expires);
  		/* Update all cached dsts too */
  		rt = rcu_dereference(fnhe->fnhe_rth_input);
@@@ -707,6 -709,7 +710,7 @@@
  		fnhe->fnhe_daddr = daddr;
  		fnhe->fnhe_gw = gw;
  		fnhe->fnhe_pmtu = pmtu;
+ 		fnhe->fnhe_mtu_locked = lock;
  		fnhe->fnhe_expires = expires;
  
  		/* Exception created; mark the cached routes for the nexthop
@@@ -788,7 -791,8 +792,8 @@@ static void __ip_do_redirect(struct rta
  				struct fib_nh *nh = &FIB_RES_NH(res);
  
  				update_or_create_fnhe(nh, fl4->daddr, new_gw,
- 						0, jiffies + ip_rt_gc_timeout);
+ 						0, false,
+ 						jiffies + ip_rt_gc_timeout);
  			}
  			if (kill_route)
  				rt->dst.obsolete = DST_OBSOLETE_KILL;
@@@ -1010,15 -1014,18 +1015,18 @@@ static void __ip_rt_update_pmtu(struct 
  {
  	struct dst_entry *dst = &rt->dst;
  	struct fib_result res;
+ 	bool lock = false;
  
- 	if (dst_metric_locked(dst, RTAX_MTU))
+ 	if (ip_mtu_locked(dst))
  		return;
  
  	if (ipv4_mtu(dst) < mtu)
  		return;
  
- 	if (mtu < ip_rt_min_pmtu)
+ 	if (mtu < ip_rt_min_pmtu) {
+ 		lock = true;
  		mtu = ip_rt_min_pmtu;
+ 	}
  
  	if (rt->rt_pmtu == mtu &&
  	    time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
@@@ -1028,7 -1035,7 +1036,7 @@@
  	if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) {
  		struct fib_nh *nh = &FIB_RES_NH(res);
  
- 		update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
+ 		update_or_create_fnhe(nh, fl4->daddr, 0, mtu, lock,
  				      jiffies + ip_rt_mtu_expires);
  	}
  	rcu_read_unlock();
@@@ -1281,7 -1288,7 +1289,7 @@@ static unsigned int ipv4_mtu(const stru
  
  	mtu = READ_ONCE(dst->dev->mtu);
  
- 	if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
+ 	if (unlikely(ip_mtu_locked(dst))) {
  		if (rt->rt_uses_gateway && mtu > 576)
  			mtu = 576;
  	}
@@@ -1394,7 -1401,7 +1402,7 @@@ struct uncached_list 
  
  static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list);
  
- static void rt_add_uncached_list(struct rtable *rt)
+ void rt_add_uncached_list(struct rtable *rt)
  {
  	struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list);
  
@@@ -1405,14 -1412,8 +1413,8 @@@
  	spin_unlock_bh(&ul->lock);
  }
  
- static void ipv4_dst_destroy(struct dst_entry *dst)
+ void rt_del_uncached_list(struct rtable *rt)
  {
- 	struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
- 	struct rtable *rt = (struct rtable *) dst;
- 
- 	if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
- 		kfree(p);
- 
  	if (!list_empty(&rt->rt_uncached)) {
  		struct uncached_list *ul = rt->rt_uncached_list;
  
@@@ -1422,6 -1423,17 +1424,17 @@@
  	}
  }
  
+ static void ipv4_dst_destroy(struct dst_entry *dst)
+ {
+ 	struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
+ 	struct rtable *rt = (struct rtable *)dst;
+ 
+ 	if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
+ 		kfree(p);
+ 
+ 	rt_del_uncached_list(rt);
+ }
+ 
  void rt_flush_dev(struct net_device *dev)
  {
  	struct net *net = dev_net(dev);
@@@ -1517,8 -1529,10 +1530,9 @@@ struct rtable *rt_dst_alloc(struct net_
  		rt->rt_is_input = 0;
  		rt->rt_iif = 0;
  		rt->rt_pmtu = 0;
+ 		rt->rt_mtu_locked = 0;
  		rt->rt_gateway = 0;
  		rt->rt_uses_gateway = 0;
 -		rt->rt_table_id = 0;
  		INIT_LIST_HEAD(&rt->rt_uncached);
  
  		rt->dst.output = ip_output;
@@@ -1654,6 -1668,19 +1668,6 @@@ static void ip_del_fnhe(struct fib_nh *
  	spin_unlock_bh(&fnhe_lock);
  }
  
 -static void set_lwt_redirect(struct rtable *rth)
 -{
 -	if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
 -		rth->dst.lwtstate->orig_output = rth->dst.output;
 -		rth->dst.output = lwtunnel_output;
 -	}
 -
 -	if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
 -		rth->dst.lwtstate->orig_input = rth->dst.input;
 -		rth->dst.input = lwtunnel_input;
 -	}
 -}
 -
  /* called in rcu_read_lock() section */
  static int __mkroute_input(struct sk_buff *skb,
  			   const struct fib_result *res,
@@@ -1736,13 -1763,15 +1750,13 @@@ rt_cache
  	}
  
  	rth->rt_is_input = 1;
 -	if (res->table)
 -		rth->rt_table_id = res->table->tb_id;
  	RT_CACHE_STAT_INC(in_slow_tot);
  
  	rth->dst.input = ip_forward;
  
  	rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag,
  		       do_cache);
 -	set_lwt_redirect(rth);
 +	lwtunnel_set_redirect(&rth->dst);
  	skb_dst_set(skb, &rth->dst);
  out:
  	err = 0;
@@@ -1758,45 -1787,44 +1772,45 @@@ static void ip_multipath_l3_keys(const 
  				 struct flow_keys *hash_keys)
  {
  	const struct iphdr *outer_iph = ip_hdr(skb);
 +	const struct iphdr *key_iph = outer_iph;
  	const struct iphdr *inner_iph;
  	const struct icmphdr *icmph;
  	struct iphdr _inner_iph;
  	struct icmphdr _icmph;
  
 -	hash_keys->addrs.v4addrs.src = outer_iph->saddr;
 -	hash_keys->addrs.v4addrs.dst = outer_iph->daddr;
  	if (likely(outer_iph->protocol != IPPROTO_ICMP))
 -		return;
 +		goto out;
  
  	if (unlikely((outer_iph->frag_off & htons(IP_OFFSET)) != 0))
 -		return;
 +		goto out;
  
  	icmph = skb_header_pointer(skb, outer_iph->ihl * 4, sizeof(_icmph),
  				   &_icmph);
  	if (!icmph)
 -		return;
 +		goto out;
  
  	if (icmph->type != ICMP_DEST_UNREACH &&
  	    icmph->type != ICMP_REDIRECT &&
  	    icmph->type != ICMP_TIME_EXCEEDED &&
  	    icmph->type != ICMP_PARAMETERPROB)
 -		return;
 +		goto out;
  
  	inner_iph = skb_header_pointer(skb,
  				       outer_iph->ihl * 4 + sizeof(_icmph),
  				       sizeof(_inner_iph), &_inner_iph);
  	if (!inner_iph)
 -		return;
 -	hash_keys->addrs.v4addrs.src = inner_iph->saddr;
 -	hash_keys->addrs.v4addrs.dst = inner_iph->daddr;
 +		goto out;
 +
 +	key_iph = inner_iph;
 +out:
 +	hash_keys->addrs.v4addrs.src = key_iph->saddr;
 +	hash_keys->addrs.v4addrs.dst = key_iph->daddr;
  }
  
  /* if skb is set it will be used and fl4 can be NULL */
 -int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
 -		       const struct sk_buff *skb)
 +int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 +		       const struct sk_buff *skb, struct flow_keys *flkeys)
  {
 -	struct net *net = fi->fib_net;
  	struct flow_keys hash_keys;
  	u32 mhash;
  
@@@ -1820,20 -1848,15 +1834,20 @@@
  			/* short-circuit if we already have L4 hash present */
  			if (skb->l4_hash)
  				return skb_get_hash_raw(skb) >> 1;
 +
  			memset(&hash_keys, 0, sizeof(hash_keys));
 -			skb_flow_dissect_flow_keys(skb, &keys, flag);
 +
 +			if (!flkeys) {
 +				skb_flow_dissect_flow_keys(skb, &keys, flag);
 +				flkeys = &keys;
 +			}
  
  			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
 -			hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src;
 -			hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst;
 -			hash_keys.ports.src = keys.ports.src;
 -			hash_keys.ports.dst = keys.ports.dst;
 -			hash_keys.basic.ip_proto = keys.basic.ip_proto;
 +			hash_keys.addrs.v4addrs.src = flkeys->addrs.v4addrs.src;
 +			hash_keys.addrs.v4addrs.dst = flkeys->addrs.v4addrs.dst;
 +			hash_keys.ports.src = flkeys->ports.src;
 +			hash_keys.ports.dst = flkeys->ports.dst;
 +			hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
  		} else {
  			memset(&hash_keys, 0, sizeof(hash_keys));
  			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
@@@ -1849,17 -1872,17 +1863,17 @@@
  
  	return mhash >> 1;
  }
 -EXPORT_SYMBOL_GPL(fib_multipath_hash);
  #endif /* CONFIG_IP_ROUTE_MULTIPATH */
  
  static int ip_mkroute_input(struct sk_buff *skb,
  			    struct fib_result *res,
  			    struct in_device *in_dev,
 -			    __be32 daddr, __be32 saddr, u32 tos)
 +			    __be32 daddr, __be32 saddr, u32 tos,
 +			    struct flow_keys *hkeys)
  {
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
  	if (res->fi && res->fi->fib_nhs > 1) {
 -		int h = fib_multipath_hash(res->fi, NULL, skb);
 +		int h = fib_multipath_hash(res->fi->fib_net, NULL, skb, hkeys);
  
  		fib_select_multipath(res, h);
  	}
@@@ -1885,14 -1908,13 +1899,14 @@@ static int ip_route_input_slow(struct s
  			       struct fib_result *res)
  {
  	struct in_device *in_dev = __in_dev_get_rcu(dev);
 +	struct flow_keys *flkeys = NULL, _flkeys;
 +	struct net    *net = dev_net(dev);
  	struct ip_tunnel_info *tun_info;
 -	struct flowi4	fl4;
 +	int		err = -EINVAL;
  	unsigned int	flags = 0;
  	u32		itag = 0;
  	struct rtable	*rth;
 -	int		err = -EINVAL;
 -	struct net    *net = dev_net(dev);
 +	struct flowi4	fl4;
  	bool do_cache;
  
  	/* IP on this device is disabled. */
@@@ -1951,10 -1973,6 +1965,10 @@@
  	fl4.daddr = daddr;
  	fl4.saddr = saddr;
  	fl4.flowi4_uid = sock_net_uid(net, NULL);
 +
 +	if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys))
 +		flkeys = &_flkeys;
 +
  	err = fib_lookup(net, &fl4, res, 0);
  	if (err != 0) {
  		if (!IN_DEV_FORWARD(in_dev))
@@@ -1980,7 -1998,7 +1994,7 @@@
  	if (res->type != RTN_UNICAST)
  		goto martian_destination;
  
 -	err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos);
 +	err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos, flkeys);
  out:	return err;
  
  brd_input:
@@@ -2022,6 -2040,8 +2036,6 @@@ local_input
  	rth->dst.tclassid = itag;
  #endif
  	rth->rt_is_input = 1;
 -	if (res->table)
 -		rth->rt_table_id = res->table->tb_id;
  
  	RT_CACHE_STAT_INC(in_slow_tot);
  	if (res->type == RTN_UNREACHABLE) {
@@@ -2250,6 -2270,8 +2264,6 @@@ add
  		return ERR_PTR(-ENOBUFS);
  
  	rth->rt_iif = orig_oif;
 -	if (res->table)
 -		rth->rt_table_id = res->table->tb_id;
  
  	RT_CACHE_STAT_INC(out_slow_tot);
  
@@@ -2271,7 -2293,7 +2285,7 @@@
  	}
  
  	rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0, do_cache);
 -	set_lwt_redirect(rth);
 +	lwtunnel_set_redirect(&rth->dst);
  
  	return rth;
  }
@@@ -2533,6 -2555,7 +2547,7 @@@ struct dst_entry *ipv4_blackhole_route(
  		rt->rt_is_input = ort->rt_is_input;
  		rt->rt_iif = ort->rt_iif;
  		rt->rt_pmtu = ort->rt_pmtu;
+ 		rt->rt_mtu_locked = ort->rt_mtu_locked;
  
  		rt->rt_genid = rt_genid_ipv4(net);
  		rt->rt_flags = ort->rt_flags;
@@@ -2635,6 -2658,8 +2650,8 @@@ static int rt_fill_info(struct net *net
  	memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics));
  	if (rt->rt_pmtu && expires)
  		metrics[RTAX_MTU - 1] = rt->rt_pmtu;
+ 	if (rt->rt_mtu_locked && expires)
+ 		metrics[RTAX_LOCK - 1] |= BIT(RTAX_MTU);
  	if (rtnetlink_put_metrics(skb, metrics) < 0)
  		goto nla_put_failure;
  
@@@ -2779,7 -2804,7 +2796,7 @@@ static int inet_rtm_getroute(struct sk_
  		rt->rt_flags |= RTCF_NOTIFY;
  
  	if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
 -		table_id = rt->rt_table_id;
 +		table_id = res.table ? res.table->tb_id : 0;
  
  	if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
  		if (!res.fi) {
@@@ -3000,7 -3025,6 +3017,7 @@@ static __net_exit void sysctl_route_net
  static __net_initdata struct pernet_operations sysctl_route_ops = {
  	.init = sysctl_route_net_init,
  	.exit = sysctl_route_net_exit,
 +	.async = true,
  };
  #endif
  
@@@ -3014,7 -3038,6 +3031,7 @@@ static __net_init int rt_genid_init(str
  
  static __net_initdata struct pernet_operations rt_genid_ops = {
  	.init = rt_genid_init,
 +	.async = true,
  };
  
  static int __net_init ipv4_inetpeer_init(struct net *net)
@@@ -3040,7 -3063,6 +3057,7 @@@ static void __net_exit ipv4_inetpeer_ex
  static __net_initdata struct pernet_operations ipv4_inetpeer_ops = {
  	.init	=	ipv4_inetpeer_init,
  	.exit	=	ipv4_inetpeer_exit,
 +	.async	=	true,
  };
  
  #ifdef CONFIG_IP_ROUTE_CLASSID
diff --combined net/ipv4/tcp.c
index d763fae1b574,8b8059b7af4d..0c31be306572
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@@ -453,7 -453,6 +453,7 @@@ void tcp_init_sock(struct sock *sk
  	sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1];
  
  	sk_sockets_allocated_inc(sk);
 +	sk->sk_route_forced_caps = NETIF_F_GSO;
  }
  EXPORT_SYMBOL(tcp_init_sock);
  
@@@ -898,7 -897,7 +898,7 @@@ static unsigned int tcp_xmit_size_goal(
  	struct tcp_sock *tp = tcp_sk(sk);
  	u32 new_size_goal, size_goal;
  
 -	if (!large_allowed || !sk_can_gso(sk))
 +	if (!large_allowed)
  		return mss_now;
  
  	/* Note : tcp_tso_autosize() will eventually split this later */
@@@ -994,9 -993,7 +994,9 @@@ new_segment
  			get_page(page);
  			skb_fill_page_desc(skb, i, page, offset, copy);
  		}
 -		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 +
 +		if (!(flags & MSG_NO_SHARED_FRAGS))
 +			skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
  
  		skb->len += copy;
  		skb->data_len += copy;
@@@ -1065,7 -1062,8 +1065,7 @@@ EXPORT_SYMBOL_GPL(do_tcp_sendpages)
  int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset,
  			size_t size, int flags)
  {
 -	if (!(sk->sk_route_caps & NETIF_F_SG) ||
 -	    !sk_check_csum_caps(sk))
 +	if (!(sk->sk_route_caps & NETIF_F_SG))
  		return sock_no_sendpage_locked(sk, page, offset, size, flags);
  
  	tcp_rate_check_app_limited(sk);  /* is sending application-limited? */
@@@ -1104,11 -1102,27 +1104,11 @@@ static int linear_payload_sz(bool first
  	return 0;
  }
  
 -static int select_size(const struct sock *sk, bool sg, bool first_skb, bool zc)
 +static int select_size(bool first_skb, bool zc)
  {
 -	const struct tcp_sock *tp = tcp_sk(sk);
 -	int tmp = tp->mss_cache;
 -
 -	if (sg) {
 -		if (zc)
 -			return 0;
 -
 -		if (sk_can_gso(sk)) {
 -			tmp = linear_payload_sz(first_skb);
 -		} else {
 -			int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
 -
 -			if (tmp >= pgbreak &&
 -			    tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
 -				tmp = pgbreak;
 -		}
 -	}
 -
 -	return tmp;
 +	if (zc)
 +		return 0;
 +	return linear_payload_sz(first_skb);
  }
  
  void tcp_free_fastopen_req(struct tcp_sock *tp)
@@@ -1173,7 -1187,7 +1173,7 @@@ int tcp_sendmsg_locked(struct sock *sk
  	int flags, err, copied = 0;
  	int mss_now = 0, size_goal, copied_syn = 0;
  	bool process_backlog = false;
 -	bool sg, zc = false;
 +	bool zc = false;
  	long timeo;
  
  	flags = msg->msg_flags;
@@@ -1191,7 -1205,7 +1191,7 @@@
  			goto out_err;
  		}
  
 -		zc = sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG;
 +		zc = sk->sk_route_caps & NETIF_F_SG;
  		if (!zc)
  			uarg->zerocopy = 0;
  	}
@@@ -1254,12 -1268,18 +1254,12 @@@ restart
  	if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
  		goto do_error;
  
 -	sg = !!(sk->sk_route_caps & NETIF_F_SG);
 -
  	while (msg_data_left(msg)) {
  		int copy = 0;
 -		int max = size_goal;
  
  		skb = tcp_write_queue_tail(sk);
 -		if (skb) {
 -			if (skb->ip_summed == CHECKSUM_NONE)
 -				max = mss_now;
 -			copy = max - skb->len;
 -		}
 +		if (skb)
 +			copy = size_goal - skb->len;
  
  		if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) {
  			bool first_skb;
@@@ -1277,17 -1297,22 +1277,17 @@@ new_segment
  				goto restart;
  			}
  			first_skb = tcp_rtx_and_write_queues_empty(sk);
 -			linear = select_size(sk, sg, first_skb, zc);
 +			linear = select_size(first_skb, zc);
  			skb = sk_stream_alloc_skb(sk, linear, sk->sk_allocation,
  						  first_skb);
  			if (!skb)
  				goto wait_for_memory;
  
  			process_backlog = true;
 -			/*
 -			 * Check whether we can use HW checksum.
 -			 */
 -			if (sk_check_csum_caps(sk))
 -				skb->ip_summed = CHECKSUM_PARTIAL;
 +			skb->ip_summed = CHECKSUM_PARTIAL;
  
  			skb_entail(sk, skb);
  			copy = size_goal;
 -			max = size_goal;
  
  			/* All packets are restored as if they have
  			 * already been sent. skb_mstamp isn't set to
@@@ -1318,7 -1343,7 +1318,7 @@@
  
  			if (!skb_can_coalesce(skb, i, pfrag->page,
  					      pfrag->offset)) {
 -				if (i >= sysctl_max_skb_frags || !sg) {
 +				if (i >= sysctl_max_skb_frags) {
  					tcp_mark_push(tp, skb);
  					goto new_segment;
  				}
@@@ -1371,7 -1396,7 +1371,7 @@@
  			goto out;
  		}
  
 -		if (skb->len < max || (flags & MSG_OOB) || unlikely(tp->repair))
 +		if (skb->len < size_goal || (flags & MSG_OOB) || unlikely(tp->repair))
  			continue;
  
  		if (forced_push(tp)) {
@@@ -3033,8 -3058,8 +3033,8 @@@ struct sk_buff *tcp_get_timestamping_op
  	u32 rate;
  
  	stats = alloc_skb(7 * nla_total_size_64bit(sizeof(u64)) +
 -			  3 * nla_total_size(sizeof(u32)) +
 -			  2 * nla_total_size(sizeof(u8)), GFP_ATOMIC);
 +			  5 * nla_total_size(sizeof(u32)) +
 +			  3 * nla_total_size(sizeof(u8)), GFP_ATOMIC);
  	if (!stats)
  		return NULL;
  
@@@ -3063,10 -3088,6 +3063,10 @@@
  
  	nla_put_u8(stats, TCP_NLA_RECUR_RETRANS, inet_csk(sk)->icsk_retransmits);
  	nla_put_u8(stats, TCP_NLA_DELIVERY_RATE_APP_LMT, !!tp->rate_app_limited);
 +	nla_put_u32(stats, TCP_NLA_SND_SSTHRESH, tp->snd_ssthresh);
 +
 +	nla_put_u32(stats, TCP_NLA_SNDQ_SIZE, tp->write_seq - tp->snd_una);
 +	nla_put_u8(stats, TCP_NLA_CA_STATE, inet_csk(sk)->icsk_ca_state);
  	return stats;
  }
  
@@@ -3545,6 -3566,7 +3545,7 @@@ int tcp_abort(struct sock *sk, int err
  
  	bh_unlock_sock(sk);
  	local_bh_enable();
+ 	tcp_write_queue_purge(sk);
  	release_sock(sk);
  	return 0;
  }
diff --combined net/ipv4/xfrm4_policy.c
index 0c752dc3f93b,fbebda67ac1b..6c76a757fa4a
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@@ -100,7 -100,10 +100,9 @@@ static int xfrm4_fill_dst(struct xfrm_d
  	xdst->u.rt.rt_gateway = rt->rt_gateway;
  	xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
  	xdst->u.rt.rt_pmtu = rt->rt_pmtu;
+ 	xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
 -	xdst->u.rt.rt_table_id = rt->rt_table_id;
  	INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
+ 	rt_add_uncached_list(&xdst->u.rt);
  
  	return 0;
  }
@@@ -240,7 -243,8 +242,8 @@@ static void xfrm4_dst_destroy(struct ds
  	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
  
  	dst_destroy_metrics_generic(dst);
- 
+ 	if (xdst->u.rt.rt_uncached_list)
+ 		rt_del_uncached_list(&xdst->u.rt);
  	xfrm_dst_destroy(xdst);
  }
  
@@@ -364,7 -368,6 +367,7 @@@ static void __net_exit xfrm4_net_exit(s
  static struct pernet_operations __net_initdata xfrm4_net_ops = {
  	.init	= xfrm4_net_init,
  	.exit	= xfrm4_net_exit,
 +	.async	= true,
  };
  
  static void __init xfrm4_policy_init(void)
@@@ -379,3 -382,4 +382,3 @@@ void __init xfrm4_init(void
  	xfrm4_protocol_init();
  	register_pernet_subsys(&xfrm4_net_ops);
  }
 -
diff --combined net/ipv6/datagram.c
index b27333d7b099,a9f7eca0b6a3..88bc2ef7c7a8
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@@ -146,10 -146,12 +146,12 @@@ int __ip6_datagram_connect(struct sock 
  	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
  	struct inet_sock	*inet = inet_sk(sk);
  	struct ipv6_pinfo	*np = inet6_sk(sk);
- 	struct in6_addr		*daddr;
+ 	struct in6_addr		*daddr, old_daddr;
+ 	__be32			fl6_flowlabel = 0;
+ 	__be32			old_fl6_flowlabel;
+ 	__be16			old_dport;
  	int			addr_type;
  	int			err;
- 	__be32			fl6_flowlabel = 0;
  
  	if (usin->sin6_family == AF_INET) {
  		if (__ipv6_only_sock(sk))
@@@ -238,9 -240,13 +240,13 @@@ ipv4_connected
  		}
  	}
  
+ 	/* save the current peer information before updating it */
+ 	old_daddr = sk->sk_v6_daddr;
+ 	old_fl6_flowlabel = np->flow_label;
+ 	old_dport = inet->inet_dport;
+ 
  	sk->sk_v6_daddr = *daddr;
  	np->flow_label = fl6_flowlabel;
- 
  	inet->inet_dport = usin->sin6_port;
  
  	/*
@@@ -250,11 -256,12 +256,12 @@@
  
  	err = ip6_datagram_dst_update(sk, true);
  	if (err) {
- 		/* Reset daddr and dport so that udp_v6_early_demux()
- 		 * fails to find this socket
+ 		/* Restore the socket peer info, to keep it consistent with
+ 		 * the old socket state
  		 */
- 		memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
- 		inet->inet_dport = 0;
+ 		sk->sk_v6_daddr = old_daddr;
+ 		np->flow_label = old_fl6_flowlabel;
+ 		inet->inet_dport = old_dport;
  		goto out;
  	}
  
@@@ -801,9 -808,8 +808,9 @@@ int ip6_datagram_send_ctl(struct net *n
  			if (addr_type != IPV6_ADDR_ANY) {
  				int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
  				if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) &&
 -				    !ipv6_chk_addr(net, &src_info->ipi6_addr,
 -						   strict ? dev : NULL, 0) &&
 +				    !ipv6_chk_addr_and_flags(net, &src_info->ipi6_addr,
 +							     dev, !strict, 0,
 +							     IFA_F_TENTATIVE) &&
  				    !ipv6_chk_acast_addr_src(net, dev,
  							     &src_info->ipi6_addr))
  					err = -EINVAL;
diff --combined net/ipv6/ip6_gre.c
index 6adbcf40cf8c,1bbd0930063e..3a98c694da5f
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@@ -126,7 -126,8 +126,8 @@@ static struct ip6_tnl *ip6gre_tunnel_lo
  	struct ip6_tnl *t, *cand = NULL;
  	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
  	int dev_type = (gre_proto == htons(ETH_P_TEB) ||
- 			gre_proto == htons(ETH_P_ERSPAN)) ?
+ 			gre_proto == htons(ETH_P_ERSPAN) ||
+ 			gre_proto == htons(ETH_P_ERSPAN2)) ?
  		       ARPHRD_ETHER : ARPHRD_IP6GRE;
  	int score, cand_score = 4;
  
@@@ -236,7 -237,7 +237,7 @@@
  		return t;
  
  	dev = ign->fb_tunnel_dev;
 -	if (dev->flags & IFF_UP)
 +	if (dev && dev->flags & IFF_UP)
  		return netdev_priv(dev);
  
  	return NULL;
@@@ -695,6 -696,9 +696,6 @@@ static netdev_tx_t __gre6_xmit(struct s
  	else
  		fl6->daddr = tunnel->parms.raddr;
  
 -	if (tunnel->parms.o_flags & TUNNEL_SEQ)
 -		tunnel->o_seqno++;
 -
  	/* Push GRE header. */
  	protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
  
@@@ -717,20 -721,14 +718,20 @@@
  		fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
  
  		dsfield = key->tos;
 -		flags = key->tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
 +		flags = key->tun_flags &
 +			(TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
  		tunnel->tun_hlen = gre_calc_hlen(flags);
  
  		gre_build_header(skb, tunnel->tun_hlen,
  				 flags, protocol,
 -				 tunnel_id_to_key32(tun_info->key.tun_id), 0);
 +				 tunnel_id_to_key32(tun_info->key.tun_id),
 +				 (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++)
 +						      : 0);
  
  	} else {
 +		if (tunnel->parms.o_flags & TUNNEL_SEQ)
 +			tunnel->o_seqno++;
 +
  		gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
  				 protocol, tunnel->parms.o_key,
  				 htonl(tunnel->o_seqno));
@@@ -905,6 -903,9 +906,9 @@@ static netdev_tx_t ip6erspan_tunnel_xmi
  		truncate = true;
  	}
  
+ 	if (skb_cow_head(skb, dev->needed_headroom))
+ 		goto tx_err;
+ 
  	t->parms.o_flags &= ~TUNNEL_KEY;
  	IPCB(skb)->flags = 0;
  
@@@ -947,6 -948,8 +951,8 @@@
  					       md->u.md2.dir,
  					       get_hwid(&md->u.md2),
  					       truncate, false);
+ 		} else {
+ 			goto tx_err;
  		}
  	} else {
  		switch (skb->protocol) {
@@@ -1056,7 -1059,7 +1062,7 @@@ static void ip6gre_tnl_link_config(stru
  
  		struct rt6_info *rt = rt6_lookup(t->net,
  						 &p->raddr, &p->laddr,
 -						 p->link, strict);
 +						 p->link, NULL, strict);
  
  		if (!rt)
  			return;
@@@ -1472,8 -1475,6 +1478,8 @@@ static int __net_init ip6gre_init_net(s
  	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
  	int err;
  
 +	if (!net_has_fallback_tunnels(net))
 +		return 0;
  	ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
  					  NET_NAME_UNKNOWN,
  					  ip6gre_tunnel_setup);
@@@ -1522,7 -1523,6 +1528,7 @@@ static struct pernet_operations ip6gre_
  	.exit_batch = ip6gre_exit_batch_net,
  	.id   = &ip6gre_net_id,
  	.size = sizeof(struct ip6gre_net),
 +	.async = true,
  };
  
  static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
@@@ -1790,12 -1790,6 +1796,12 @@@ static void ip6gre_tap_setup(struct net
  	netif_keep_dst(dev);
  }
  
 +bool is_ip6gretap_dev(const struct net_device *dev)
 +{
 +	return dev->netdev_ops == &ip6gre_tap_netdev_ops;
 +}
 +EXPORT_SYMBOL_GPL(is_ip6gretap_dev);
 +
  static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
  				       struct ip_tunnel_encap *ipencap)
  {
diff --combined net/ipv6/ndisc.c
index 10024eb0c521,ba5e04c6ae17..d1d0b2fa7a07
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@@ -527,7 -527,7 +527,7 @@@ void ndisc_send_na(struct net_device *d
  	}
  
  	if (!dev->addr_len)
 -		inc_opt = 0;
 +		inc_opt = false;
  	if (inc_opt)
  		optlen += ndisc_opt_addr_space(dev,
  					       NDISC_NEIGHBOUR_ADVERTISEMENT);
@@@ -707,7 -707,7 +707,7 @@@ static void ndisc_solicit(struct neighb
  	int probes = atomic_read(&neigh->probes);
  
  	if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
 -					   dev, 1,
 +					   dev, false, 1,
  					   IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
  		saddr = &ipv6_hdr(skb)->saddr;
  	probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
@@@ -1554,7 -1554,8 +1554,8 @@@ static void ndisc_fill_redirect_hdr_opt
  	*(opt++) = (rd_len >> 3);
  	opt += 6;
  
- 	memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
+ 	skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
+ 		      rd_len - 8);
  }
  
  void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
@@@ -1882,7 -1883,6 +1883,7 @@@ static void __net_exit ndisc_net_exit(s
  static struct pernet_operations ndisc_net_ops = {
  	.init = ndisc_net_init,
  	.exit = ndisc_net_exit,
 +	.async = true,
  };
  
  int __init ndisc_init(void)
diff --combined net/ipv6/route.c
index 939d122e71b4,b0d5c64e1978..a2ed9fdd58d4
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@@ -128,7 -128,7 +128,7 @@@ struct uncached_list 
  
  static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list);
  
- static void rt6_uncached_list_add(struct rt6_info *rt)
+ void rt6_uncached_list_add(struct rt6_info *rt)
  {
  	struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
  
@@@ -139,7 -139,7 +139,7 @@@
  	spin_unlock_bh(&ul->lock);
  }
  
- static void rt6_uncached_list_del(struct rt6_info *rt)
+ void rt6_uncached_list_del(struct rt6_info *rt)
  {
  	if (!list_empty(&rt->rt6i_uncached)) {
  		struct uncached_list *ul = rt->rt6i_uncached_list;
@@@ -450,10 -450,8 +450,10 @@@ static bool rt6_check_expired(const str
  	return false;
  }
  
 -static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
 +static struct rt6_info *rt6_multipath_select(const struct net *net,
 +					     struct rt6_info *match,
  					     struct flowi6 *fl6, int oif,
 +					     const struct sk_buff *skb,
  					     int strict)
  {
  	struct rt6_info *sibling, *next_sibling;
@@@ -462,7 -460,7 +462,7 @@@
  	 * case it will always be non-zero. Otherwise now is the time to do it.
  	 */
  	if (!fl6->mp_hash)
 -		fl6->mp_hash = rt6_multipath_hash(fl6, NULL);
 +		fl6->mp_hash = rt6_multipath_hash(net, fl6, skb, NULL);
  
  	if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound))
  		return match;
@@@ -916,9 -914,7 +916,9 @@@ static bool ip6_hold_safe(struct net *n
  
  static struct rt6_info *ip6_pol_route_lookup(struct net *net,
  					     struct fib6_table *table,
 -					     struct flowi6 *fl6, int flags)
 +					     struct flowi6 *fl6,
 +					     const struct sk_buff *skb,
 +					     int flags)
  {
  	struct rt6_info *rt, *rt_cache;
  	struct fib6_node *fn;
@@@ -933,8 -929,8 +933,8 @@@ restart
  		rt = rt6_device_match(net, rt, &fl6->saddr,
  				      fl6->flowi6_oif, flags);
  		if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0)
 -			rt = rt6_multipath_select(rt, fl6,
 -						  fl6->flowi6_oif, flags);
 +			rt = rt6_multipath_select(net, rt, fl6, fl6->flowi6_oif,
 +						  skb, flags);
  	}
  	if (rt == net->ipv6.ip6_null_entry) {
  		fn = fib6_backtrack(fn, &fl6->saddr);
@@@ -958,15 -954,14 +958,15 @@@
  }
  
  struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
 -				    int flags)
 +				   const struct sk_buff *skb, int flags)
  {
 -	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup);
 +	return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_lookup);
  }
  EXPORT_SYMBOL_GPL(ip6_route_lookup);
  
  struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
 -			    const struct in6_addr *saddr, int oif, int strict)
 +			    const struct in6_addr *saddr, int oif,
 +			    const struct sk_buff *skb, int strict)
  {
  	struct flowi6 fl6 = {
  		.flowi6_oif = oif,
@@@ -980,7 -975,7 +980,7 @@@
  		flags |= RT6_LOOKUP_F_HAS_SADDR;
  	}
  
 -	dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup);
 +	dst = fib6_rule_lookup(net, &fl6, skb, flags, ip6_pol_route_lookup);
  	if (dst->error == 0)
  		return (struct rt6_info *) dst;
  
@@@ -1514,7 -1509,30 +1514,30 @@@ static void rt6_exceptions_remove_prefs
  	}
  }
  
- static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu)
+ static bool rt6_mtu_change_route_allowed(struct inet6_dev *idev,
+ 					 struct rt6_info *rt, int mtu)
+ {
+ 	/* If the new MTU is lower than the route PMTU, this new MTU will be the
+ 	 * lowest MTU in the path: always allow updating the route PMTU to
+ 	 * reflect PMTU decreases.
+ 	 *
+ 	 * If the new MTU is higher, and the route PMTU is equal to the local
+ 	 * MTU, this means the old MTU is the lowest in the path, so allow
+ 	 * updating it: if other nodes now have lower MTUs, PMTU discovery will
+ 	 * handle this.
+ 	 */
+ 
+ 	if (dst_mtu(&rt->dst) >= mtu)
+ 		return true;
+ 
+ 	if (dst_mtu(&rt->dst) == idev->cnf.mtu6)
+ 		return true;
+ 
+ 	return false;
+ }
+ 
+ static void rt6_exceptions_update_pmtu(struct inet6_dev *idev,
+ 				       struct rt6_info *rt, int mtu)
  {
  	struct rt6_exception_bucket *bucket;
  	struct rt6_exception *rt6_ex;
@@@ -1523,20 -1541,22 +1546,22 @@@
  	bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
  					lockdep_is_held(&rt6_exception_lock));
  
- 	if (bucket) {
- 		for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
- 			hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
- 				struct rt6_info *entry = rt6_ex->rt6i;
- 				/* For RTF_CACHE with rt6i_pmtu == 0
- 				 * (i.e. a redirected route),
- 				 * the metrics of its rt->dst.from has already
- 				 * been updated.
- 				 */
- 				if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu)
- 					entry->rt6i_pmtu = mtu;
- 			}
- 			bucket++;
+ 	if (!bucket)
+ 		return;
+ 
+ 	for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
+ 		hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
+ 			struct rt6_info *entry = rt6_ex->rt6i;
+ 
+ 			/* For RTF_CACHE with rt6i_pmtu == 0 (i.e. a redirected
+ 			 * route), the metrics of its rt->dst.from have already
+ 			 * been updated.
+ 			 */
+ 			if (entry->rt6i_pmtu &&
+ 			    rt6_mtu_change_route_allowed(idev, entry, mtu))
+ 				entry->rt6i_pmtu = mtu;
  		}
+ 		bucket++;
  	}
  }
  
@@@ -1652,8 -1672,7 +1677,8 @@@ void rt6_age_exceptions(struct rt6_inf
  }
  
  struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 -			       int oif, struct flowi6 *fl6, int flags)
 +			       int oif, struct flowi6 *fl6,
 +			       const struct sk_buff *skb, int flags)
  {
  	struct fib6_node *fn, *saved_fn;
  	struct rt6_info *rt, *rt_cache;
@@@ -1675,7 -1694,7 +1700,7 @@@
  redo_rt6_select:
  	rt = rt6_select(net, fn, oif, strict);
  	if (rt->rt6i_nsiblings)
 -		rt = rt6_multipath_select(rt, fl6, oif, strict);
 +		rt = rt6_multipath_select(net, rt, fl6, oif, skb, strict);
  	if (rt == net->ipv6.ip6_null_entry) {
  		fn = fib6_backtrack(fn, &fl6->saddr);
  		if (fn)
@@@ -1774,35 -1793,28 +1799,35 @@@ uncached_rt_out
  }
  EXPORT_SYMBOL_GPL(ip6_pol_route);
  
 -static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
 -					    struct flowi6 *fl6, int flags)
 +static struct rt6_info *ip6_pol_route_input(struct net *net,
 +					    struct fib6_table *table,
 +					    struct flowi6 *fl6,
 +					    const struct sk_buff *skb,
 +					    int flags)
  {
 -	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
 +	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, skb, flags);
  }
  
  struct dst_entry *ip6_route_input_lookup(struct net *net,
  					 struct net_device *dev,
 -					 struct flowi6 *fl6, int flags)
 +					 struct flowi6 *fl6,
 +					 const struct sk_buff *skb,
 +					 int flags)
  {
  	if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
  		flags |= RT6_LOOKUP_F_IFACE;
  
 -	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
 +	return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_input);
  }
  EXPORT_SYMBOL_GPL(ip6_route_input_lookup);
  
  static void ip6_multipath_l3_keys(const struct sk_buff *skb,
 -				  struct flow_keys *keys)
 +				  struct flow_keys *keys,
 +				  struct flow_keys *flkeys)
  {
  	const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
  	const struct ipv6hdr *key_iph = outer_iph;
 +	struct flow_keys *_flkeys = flkeys;
  	const struct ipv6hdr *inner_iph;
  	const struct icmp6hdr *icmph;
  	struct ipv6hdr _inner_iph;
@@@ -1824,76 -1836,26 +1849,76 @@@
  		goto out;
  
  	key_iph = inner_iph;
 +	_flkeys = NULL;
  out:
 -	memset(keys, 0, sizeof(*keys));
 -	keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 -	keys->addrs.v6addrs.src = key_iph->saddr;
 -	keys->addrs.v6addrs.dst = key_iph->daddr;
 -	keys->tags.flow_label = ip6_flowinfo(key_iph);
 -	keys->basic.ip_proto = key_iph->nexthdr;
 +	if (_flkeys) {
 +		keys->addrs.v6addrs.src = _flkeys->addrs.v6addrs.src;
 +		keys->addrs.v6addrs.dst = _flkeys->addrs.v6addrs.dst;
 +		keys->tags.flow_label = _flkeys->tags.flow_label;
 +		keys->basic.ip_proto = _flkeys->basic.ip_proto;
 +	} else {
 +		keys->addrs.v6addrs.src = key_iph->saddr;
 +		keys->addrs.v6addrs.dst = key_iph->daddr;
 +		keys->tags.flow_label = ip6_flowinfo(key_iph);
 +		keys->basic.ip_proto = key_iph->nexthdr;
 +	}
  }
  
  /* if skb is set it will be used and fl6 can be NULL */
 -u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb)
 +u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
 +		       const struct sk_buff *skb, struct flow_keys *flkeys)
  {
  	struct flow_keys hash_keys;
 +	u32 mhash;
  
 -	if (skb) {
 -		ip6_multipath_l3_keys(skb, &hash_keys);
 -		return flow_hash_from_keys(&hash_keys) >> 1;
 +	switch (ip6_multipath_hash_policy(net)) {
 +	case 0:
 +		memset(&hash_keys, 0, sizeof(hash_keys));
 +		hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 +		if (skb) {
 +			ip6_multipath_l3_keys(skb, &hash_keys, flkeys);
 +		} else {
 +			hash_keys.addrs.v6addrs.src = fl6->saddr;
 +			hash_keys.addrs.v6addrs.dst = fl6->daddr;
 +			hash_keys.tags.flow_label = (__force u32)fl6->flowlabel;
 +			hash_keys.basic.ip_proto = fl6->flowi6_proto;
 +		}
 +		break;
 +	case 1:
 +		if (skb) {
 +			unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
 +			struct flow_keys keys;
 +
 +			/* short-circuit if we already have L4 hash present */
 +			if (skb->l4_hash)
 +				return skb_get_hash_raw(skb) >> 1;
 +
 +			memset(&hash_keys, 0, sizeof(hash_keys));
 +
 +                        if (!flkeys) {
 +				skb_flow_dissect_flow_keys(skb, &keys, flag);
 +				flkeys = &keys;
 +			}
 +			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 +			hash_keys.addrs.v6addrs.src = flkeys->addrs.v6addrs.src;
 +			hash_keys.addrs.v6addrs.dst = flkeys->addrs.v6addrs.dst;
 +			hash_keys.ports.src = flkeys->ports.src;
 +			hash_keys.ports.dst = flkeys->ports.dst;
 +			hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
 +		} else {
 +			memset(&hash_keys, 0, sizeof(hash_keys));
 +			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 +			hash_keys.addrs.v6addrs.src = fl6->saddr;
 +			hash_keys.addrs.v6addrs.dst = fl6->daddr;
 +			hash_keys.ports.src = fl6->fl6_sport;
 +			hash_keys.ports.dst = fl6->fl6_dport;
 +			hash_keys.basic.ip_proto = fl6->flowi6_proto;
 +		}
 +		break;
  	}
 +	mhash = flow_hash_from_keys(&hash_keys);
  
 -	return get_hash_from_flowi6(fl6) >> 1;
 +	return mhash >> 1;
  }
  
  void ip6_route_input(struct sk_buff *skb)
@@@ -1910,29 -1872,20 +1935,29 @@@
  		.flowi6_mark = skb->mark,
  		.flowi6_proto = iph->nexthdr,
  	};
 +	struct flow_keys *flkeys = NULL, _flkeys;
  
  	tun_info = skb_tunnel_info(skb);
  	if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX))
  		fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id;
 +
 +	if (fib6_rules_early_flow_dissect(net, skb, &fl6, &_flkeys))
 +		flkeys = &_flkeys;
 +
  	if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6))
 -		fl6.mp_hash = rt6_multipath_hash(&fl6, skb);
 +		fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, flkeys);
  	skb_dst_drop(skb);
 -	skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
 +	skb_dst_set(skb,
 +		    ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags));
  }
  
 -static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
 -					     struct flowi6 *fl6, int flags)
 +static struct rt6_info *ip6_pol_route_output(struct net *net,
 +					     struct fib6_table *table,
 +					     struct flowi6 *fl6,
 +					     const struct sk_buff *skb,
 +					     int flags)
  {
 -	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
 +	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, skb, flags);
  }
  
  struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
@@@ -1960,7 -1913,7 +1985,7 @@@
  	else if (sk)
  		flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
  
 -	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
 +	return fib6_rule_lookup(net, fl6, NULL, flags, ip6_pol_route_output);
  }
  EXPORT_SYMBOL_GPL(ip6_route_output_flags);
  
@@@ -2209,7 -2162,6 +2234,7 @@@ struct ip6rd_flowi 
  static struct rt6_info *__ip6_route_redirect(struct net *net,
  					     struct fib6_table *table,
  					     struct flowi6 *fl6,
 +					     const struct sk_buff *skb,
  					     int flags)
  {
  	struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
@@@ -2283,9 -2235,8 +2308,9 @@@ out
  };
  
  static struct dst_entry *ip6_route_redirect(struct net *net,
 -					const struct flowi6 *fl6,
 -					const struct in6_addr *gateway)
 +					    const struct flowi6 *fl6,
 +					    const struct sk_buff *skb,
 +					    const struct in6_addr *gateway)
  {
  	int flags = RT6_LOOKUP_F_HAS_SADDR;
  	struct ip6rd_flowi rdfl;
@@@ -2293,7 -2244,7 +2318,7 @@@
  	rdfl.fl6 = *fl6;
  	rdfl.gateway = *gateway;
  
 -	return fib6_rule_lookup(net, &rdfl.fl6,
 +	return fib6_rule_lookup(net, &rdfl.fl6, skb,
  				flags, __ip6_route_redirect);
  }
  
@@@ -2313,7 -2264,7 +2338,7 @@@ void ip6_redirect(struct sk_buff *skb, 
  	fl6.flowlabel = ip6_flowinfo(iph);
  	fl6.flowi6_uid = uid;
  
 -	dst = ip6_route_redirect(net, &fl6, &ipv6_hdr(skb)->saddr);
 +	dst = ip6_route_redirect(net, &fl6, skb, &ipv6_hdr(skb)->saddr);
  	rt6_do_redirect(dst, NULL, skb);
  	dst_release(dst);
  }
@@@ -2335,7 -2286,7 +2360,7 @@@ void ip6_redirect_no_header(struct sk_b
  	fl6.saddr = iph->daddr;
  	fl6.flowi6_uid = sock_net_uid(net, NULL);
  
 -	dst = ip6_route_redirect(net, &fl6, &iph->saddr);
 +	dst = ip6_route_redirect(net, &fl6, skb, &iph->saddr);
  	rt6_do_redirect(dst, NULL, skb);
  	dst_release(dst);
  }
@@@ -2537,7 -2488,7 +2562,7 @@@ static struct rt6_info *ip6_nh_lookup_t
  		flags |= RT6_LOOKUP_F_HAS_SADDR;
  
  	flags |= RT6_LOOKUP_F_IGNORE_LINKSTATE;
 -	rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags);
 +	rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, NULL, flags);
  
  	/* if table lookup failed, fall back to full lookup */
  	if (rt == net->ipv6.ip6_null_entry) {
@@@ -2550,7 -2501,7 +2575,7 @@@
  
  static int ip6_route_check_nh_onlink(struct net *net,
  				     struct fib6_config *cfg,
 -				     struct net_device *dev,
 +				     const struct net_device *dev,
  				     struct netlink_ext_ack *extack)
  {
  	u32 tbid = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
@@@ -2600,7 -2551,7 +2625,7 @@@ static int ip6_route_check_nh(struct ne
  	}
  
  	if (!grt)
 -		grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
 +		grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, NULL, 1);
  
  	if (!grt)
  		goto out;
@@@ -2626,79 -2577,6 +2651,79 @@@ out
  	return err;
  }
  
 +static int ip6_validate_gw(struct net *net, struct fib6_config *cfg,
 +			   struct net_device **_dev, struct inet6_dev **idev,
 +			   struct netlink_ext_ack *extack)
 +{
 +	const struct in6_addr *gw_addr = &cfg->fc_gateway;
 +	int gwa_type = ipv6_addr_type(gw_addr);
 +	bool skip_dev = gwa_type & IPV6_ADDR_LINKLOCAL ? false : true;
 +	const struct net_device *dev = *_dev;
 +	bool need_addr_check = !dev;
 +	int err = -EINVAL;
 +
 +	/* if gw_addr is local we will fail to detect this in case
 +	 * address is still TENTATIVE (DAD in progress). rt6_lookup()
 +	 * will return already-added prefix route via interface that
 +	 * prefix route was assigned to, which might be non-loopback.
 +	 */
 +	if (dev &&
 +	    ipv6_chk_addr_and_flags(net, gw_addr, dev, skip_dev, 0, 0)) {
 +		NL_SET_ERR_MSG(extack, "Gateway can not be a local address");
 +		goto out;
 +	}
 +
 +	if (gwa_type != (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST)) {
 +		/* IPv6 strictly inhibits using not link-local
 +		 * addresses as nexthop address.
 +		 * Otherwise, router will not able to send redirects.
 +		 * It is very good, but in some (rare!) circumstances
 +		 * (SIT, PtP, NBMA NOARP links) it is handy to allow
 +		 * some exceptions. --ANK
 +		 * We allow IPv4-mapped nexthops to support RFC4798-type
 +		 * addressing
 +		 */
 +		if (!(gwa_type & (IPV6_ADDR_UNICAST | IPV6_ADDR_MAPPED))) {
 +			NL_SET_ERR_MSG(extack, "Invalid gateway address");
 +			goto out;
 +		}
 +
 +		if (cfg->fc_flags & RTNH_F_ONLINK)
 +			err = ip6_route_check_nh_onlink(net, cfg, dev, extack);
 +		else
 +			err = ip6_route_check_nh(net, cfg, _dev, idev);
 +
 +		if (err)
 +			goto out;
 +	}
 +
 +	/* reload in case device was changed */
 +	dev = *_dev;
 +
 +	err = -EINVAL;
 +	if (!dev) {
 +		NL_SET_ERR_MSG(extack, "Egress device not specified");
 +		goto out;
 +	} else if (dev->flags & IFF_LOOPBACK) {
 +		NL_SET_ERR_MSG(extack,
 +			       "Egress device can not be loopback device for this route");
 +		goto out;
 +	}
 +
 +	/* if we did not check gw_addr above, do so now that the
 +	 * egress device has been resolved.
 +	 */
 +	if (need_addr_check &&
 +	    ipv6_chk_addr_and_flags(net, gw_addr, dev, skip_dev, 0, 0)) {
 +		NL_SET_ERR_MSG(extack, "Gateway can not be a local address");
 +		goto out;
 +	}
 +
 +	err = 0;
 +out:
 +	return err;
 +}
 +
  static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
  					      struct netlink_ext_ack *extack)
  {
@@@ -2818,7 -2696,14 +2843,7 @@@
  		if (err)
  			goto out;
  		rt->dst.lwtstate = lwtstate_get(lwtstate);
 -		if (lwtunnel_output_redirect(rt->dst.lwtstate)) {
 -			rt->dst.lwtstate->orig_output = rt->dst.output;
 -			rt->dst.output = lwtunnel_output;
 -		}
 -		if (lwtunnel_input_redirect(rt->dst.lwtstate)) {
 -			rt->dst.lwtstate->orig_input = rt->dst.input;
 -			rt->dst.input = lwtunnel_input;
 -		}
 +		lwtunnel_set_redirect(&rt->dst);
  	}
  
  	ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
@@@ -2881,11 -2766,61 +2906,11 @@@
  	}
  
  	if (cfg->fc_flags & RTF_GATEWAY) {
 -		const struct in6_addr *gw_addr;
 -		int gwa_type;
 -
 -		gw_addr = &cfg->fc_gateway;
 -		gwa_type = ipv6_addr_type(gw_addr);
 -
 -		/* if gw_addr is local we will fail to detect this in case
 -		 * address is still TENTATIVE (DAD in progress). rt6_lookup()
 -		 * will return already-added prefix route via interface that
 -		 * prefix route was assigned to, which might be non-loopback.
 -		 */
 -		err = -EINVAL;
 -		if (ipv6_chk_addr_and_flags(net, gw_addr,
 -					    gwa_type & IPV6_ADDR_LINKLOCAL ?
 -					    dev : NULL, 0, 0)) {
 -			NL_SET_ERR_MSG(extack, "Invalid gateway address");
 +		err = ip6_validate_gw(net, cfg, &dev, &idev, extack);
 +		if (err)
  			goto out;
 -		}
 -		rt->rt6i_gateway = *gw_addr;
 -
 -		if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
 -			/* IPv6 strictly inhibits using not link-local
 -			   addresses as nexthop address.
 -			   Otherwise, router will not able to send redirects.
 -			   It is very good, but in some (rare!) circumstances
 -			   (SIT, PtP, NBMA NOARP links) it is handy to allow
 -			   some exceptions. --ANK
 -			   We allow IPv4-mapped nexthops to support RFC4798-type
 -			   addressing
 -			 */
 -			if (!(gwa_type & (IPV6_ADDR_UNICAST |
 -					  IPV6_ADDR_MAPPED))) {
 -				NL_SET_ERR_MSG(extack,
 -					       "Invalid gateway address");
 -				goto out;
 -			}
  
 -			if (cfg->fc_flags & RTNH_F_ONLINK) {
 -				err = ip6_route_check_nh_onlink(net, cfg, dev,
 -								extack);
 -			} else {
 -				err = ip6_route_check_nh(net, cfg, &dev, &idev);
 -			}
 -			if (err)
 -				goto out;
 -		}
 -		err = -EINVAL;
 -		if (!dev) {
 -			NL_SET_ERR_MSG(extack, "Egress device not specified");
 -			goto out;
 -		} else if (dev->flags & IFF_LOOPBACK) {
 -			NL_SET_ERR_MSG(extack,
 -				       "Egress device can not be loopback device for this route");
 -			goto out;
 -		}
 +		rt->rt6i_gateway = cfg->fc_gateway;
  	}
  
  	err = -ENODEV;
@@@ -3899,25 -3834,13 +3924,13 @@@ static int rt6_mtu_change_route(struct 
  	   Since RFC 1981 doesn't include administrative MTU increase
  	   update PMTU increase is a MUST. (i.e. jumbo frame)
  	 */
- 	/*
- 	   If new MTU is less than route PMTU, this new MTU will be the
- 	   lowest MTU in the path, update the route PMTU to reflect PMTU
- 	   decreases; if new MTU is greater than route PMTU, and the
- 	   old MTU is the lowest MTU in the path, update the route PMTU
- 	   to reflect the increase. In this case if the other nodes' MTU
- 	   also have the lowest MTU, TOO BIG MESSAGE will be lead to
- 	   PMTU discovery.
- 	 */
  	if (rt->dst.dev == arg->dev &&
- 	    dst_metric_raw(&rt->dst, RTAX_MTU) &&
  	    !dst_metric_locked(&rt->dst, RTAX_MTU)) {
  		spin_lock_bh(&rt6_exception_lock);
- 		if (dst_mtu(&rt->dst) >= arg->mtu ||
- 		    (dst_mtu(&rt->dst) < arg->mtu &&
- 		     dst_mtu(&rt->dst) == idev->cnf.mtu6)) {
+ 		if (dst_metric_raw(&rt->dst, RTAX_MTU) &&
+ 		    rt6_mtu_change_route_allowed(idev, rt, arg->mtu))
  			dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
- 		}
- 		rt6_exceptions_update_pmtu(rt, arg->mtu);
+ 		rt6_exceptions_update_pmtu(idev, rt, arg->mtu);
  		spin_unlock_bh(&rt6_exception_lock);
  	}
  	return 0;
@@@ -4189,6 -4112,7 +4202,7 @@@ static int ip6_route_multipath_add(stru
  				r_cfg.fc_encap_type = nla_get_u16(nla);
  		}
  
+ 		r_cfg.fc_flags |= (rtnh->rtnh_flags & RTNH_F_ONLINK);
  		rt = ip6_route_info_create(&r_cfg, extack);
  		if (IS_ERR(rt)) {
  			err = PTR_ERR(rt);
@@@ -4688,7 -4612,7 +4702,7 @@@ static int inet6_rtm_getroute(struct sk
  		if (!ipv6_addr_any(&fl6.saddr))
  			flags |= RT6_LOOKUP_F_HAS_SADDR;
  
 -		dst = ip6_route_input_lookup(net, dev, &fl6, flags);
 +		dst = ip6_route_input_lookup(net, dev, &fl6, NULL, flags);
  
  		rcu_read_unlock();
  	} else {
@@@ -5069,7 -4993,6 +5083,7 @@@ static void __net_exit ip6_route_net_ex
  static struct pernet_operations ip6_route_net_ops = {
  	.init = ip6_route_net_init,
  	.exit = ip6_route_net_exit,
 +	.async = true,
  };
  
  static int __net_init ipv6_inetpeer_init(struct net *net)
@@@ -5095,13 -5018,11 +5109,13 @@@ static void __net_exit ipv6_inetpeer_ex
  static struct pernet_operations ipv6_inetpeer_ops = {
  	.init	=	ipv6_inetpeer_init,
  	.exit	=	ipv6_inetpeer_exit,
 +	.async	=	true,
  };
  
  static struct pernet_operations ip6_route_net_late_ops = {
  	.init = ip6_route_net_init_late,
  	.exit = ip6_route_net_exit_late,
 +	.async = true,
  };
  
  static struct notifier_block ip6_route_dev_notifier = {
diff --combined net/ipv6/xfrm6_policy.c
index 88cd0c90fa81,416fe67271a9..cbb270bd81b0
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@@ -113,6 -113,9 +113,9 @@@ static int xfrm6_fill_dst(struct xfrm_d
  	xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
  	xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
  	xdst->u.rt6.rt6i_src = rt->rt6i_src;
+ 	INIT_LIST_HEAD(&xdst->u.rt6.rt6i_uncached);
+ 	rt6_uncached_list_add(&xdst->u.rt6);
+ 	atomic_inc(&dev_net(dev)->ipv6.rt6_stats->fib_rt_uncache);
  
  	return 0;
  }
@@@ -244,6 -247,8 +247,8 @@@ static void xfrm6_dst_destroy(struct ds
  	if (likely(xdst->u.rt6.rt6i_idev))
  		in6_dev_put(xdst->u.rt6.rt6i_idev);
  	dst_destroy_metrics_generic(dst);
+ 	if (xdst->u.rt6.rt6i_uncached_list)
+ 		rt6_uncached_list_del(&xdst->u.rt6);
  	xfrm_dst_destroy(xdst);
  }
  
@@@ -395,7 -400,6 +400,7 @@@ static void __net_exit xfrm6_net_exit(s
  static struct pernet_operations xfrm6_net_ops = {
  	.init	= xfrm6_net_init,
  	.exit	= xfrm6_net_exit,
 +	.async	= true,
  };
  
  int __init xfrm6_init(void)
diff --combined net/iucv/af_iucv.c
index 81ce15ffb878,9e2643ab4ccb..893a022f9620
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@@ -989,13 -989,14 +989,13 @@@ done
  }
  
  static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
 -			     int *len, int peer)
 +			     int peer)
  {
  	struct sockaddr_iucv *siucv = (struct sockaddr_iucv *) addr;
  	struct sock *sk = sock->sk;
  	struct iucv_sock *iucv = iucv_sk(sk);
  
  	addr->sa_family = AF_IUCV;
 -	*len = sizeof(struct sockaddr_iucv);
  
  	if (peer) {
  		memcpy(siucv->siucv_user_id, iucv->dst_user_id, 8);
@@@ -1008,7 -1009,7 +1008,7 @@@
  	memset(&siucv->siucv_addr, 0, sizeof(siucv->siucv_addr));
  	memset(&siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid));
  
 -	return 0;
 +	return sizeof(struct sockaddr_iucv);
  }
  
  /**
@@@ -2432,9 -2433,11 +2432,11 @@@ static int afiucv_iucv_init(void
  	af_iucv_dev->driver = &af_iucv_driver;
  	err = device_register(af_iucv_dev);
  	if (err)
- 		goto out_driver;
+ 		goto out_iucv_dev;
  	return 0;
  
+ out_iucv_dev:
+ 	put_device(af_iucv_dev);
  out_driver:
  	driver_unregister(&af_iucv_driver);
  out_iucv:
diff --combined net/kcm/kcmsock.c
index a6cd0712e063,34355fd19f27..516cfad71b85
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@@ -1381,24 -1381,32 +1381,32 @@@ static int kcm_attach(struct socket *so
  		.parse_msg = kcm_parse_func_strparser,
  		.read_sock_done = kcm_read_sock_done,
  	};
- 	int err;
+ 	int err = 0;
  
  	csk = csock->sk;
  	if (!csk)
  		return -EINVAL;
  
+ 	lock_sock(csk);
+ 
  	/* Only allow TCP sockets to be attached for now */
  	if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) ||
- 	    csk->sk_protocol != IPPROTO_TCP)
- 		return -EOPNOTSUPP;
+ 	    csk->sk_protocol != IPPROTO_TCP) {
+ 		err = -EOPNOTSUPP;
+ 		goto out;
+ 	}
  
  	/* Don't allow listeners or closed sockets */
- 	if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE)
- 		return -EOPNOTSUPP;
+ 	if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) {
+ 		err = -EOPNOTSUPP;
+ 		goto out;
+ 	}
  
  	psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
- 	if (!psock)
- 		return -ENOMEM;
+ 	if (!psock) {
+ 		err = -ENOMEM;
+ 		goto out;
+ 	}
  
  	psock->mux = mux;
  	psock->sk = csk;
@@@ -1407,7 -1415,7 +1415,7 @@@
  	err = strp_init(&psock->strp, csk, &cb);
  	if (err) {
  		kmem_cache_free(kcm_psockp, psock);
- 		return err;
+ 		goto out;
  	}
  
  	write_lock_bh(&csk->sk_callback_lock);
@@@ -1417,10 -1425,10 +1425,11 @@@
  	 */
  	if (csk->sk_user_data) {
  		write_unlock_bh(&csk->sk_callback_lock);
 +		strp_stop(&psock->strp);
  		strp_done(&psock->strp);
  		kmem_cache_free(kcm_psockp, psock);
- 		return -EALREADY;
+ 		err = -EALREADY;
+ 		goto out;
  	}
  
  	psock->save_data_ready = csk->sk_data_ready;
@@@ -1456,7 -1464,10 +1465,10 @@@
  	/* Schedule RX work in case there are already bytes queued */
  	strp_check_rcv(&psock->strp);
  
- 	return 0;
+ out:
+ 	release_sock(csk);
+ 
+ 	return err;
  }
  
  static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info)
@@@ -1508,6 -1519,7 +1520,7 @@@ static void kcm_unattach(struct kcm_pso
  
  	if (WARN_ON(psock->rx_kcm)) {
  		write_unlock_bh(&csk->sk_callback_lock);
+ 		release_sock(csk);
  		return;
  	}
  
@@@ -2015,7 -2027,6 +2028,7 @@@ static struct pernet_operations kcm_net
  	.exit = kcm_exit_net,
  	.id   = &kcm_net_id,
  	.size = sizeof(struct kcm_net),
 +	.async = true,
  };
  
  static int __init kcm_init(void)
diff --combined net/l2tp/l2tp_core.c
index 189a12a5e4ac,14b67dfacc4b..b86868da50d4
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@@ -111,6 -111,13 +111,13 @@@ struct l2tp_net 
  	spinlock_t l2tp_session_hlist_lock;
  };
  
+ #if IS_ENABLED(CONFIG_IPV6)
+ static bool l2tp_sk_is_v6(struct sock *sk)
+ {
+ 	return sk->sk_family == PF_INET6 &&
+ 	       !ipv6_addr_v4mapped(&sk->sk_v6_daddr);
+ }
+ #endif
  
  static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
  {
@@@ -1049,7 -1056,7 +1056,7 @@@ static int l2tp_xmit_core(struct l2tp_s
  	/* Queue the packet to IP for output */
  	skb->ignore_df = 1;
  #if IS_ENABLED(CONFIG_IPV6)
- 	if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
+ 	if (l2tp_sk_is_v6(tunnel->sock))
  		error = inet6_csk_xmit(tunnel->sock, skb, NULL);
  	else
  #endif
@@@ -1112,6 -1119,15 +1119,15 @@@ int l2tp_xmit_skb(struct l2tp_session *
  		goto out_unlock;
  	}
  
+ 	/* The user-space may change the connection status for the user-space
+ 	 * provided socket at run time: we must check it under the socket lock
+ 	 */
+ 	if (tunnel->fd >= 0 && sk->sk_state != TCP_ESTABLISHED) {
+ 		kfree_skb(skb);
+ 		ret = NET_XMIT_DROP;
+ 		goto out_unlock;
+ 	}
+ 
  	/* Get routing info from the tunnel socket */
  	skb_dst_drop(skb);
  	skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
@@@ -1131,7 -1147,7 +1147,7 @@@
  
  		/* Calculate UDP checksum if configured to do so */
  #if IS_ENABLED(CONFIG_IPV6)
- 		if (sk->sk_family == PF_INET6 && !tunnel->v4mapped)
+ 		if (l2tp_sk_is_v6(sk))
  			udp6_set_csum(udp_get_no_check6_tx(sk),
  				      skb, &inet6_sk(sk)->saddr,
  				      &sk->sk_v6_daddr, udp_len);
@@@ -1457,9 -1473,14 +1473,14 @@@ int l2tp_tunnel_create(struct net *net
  		encap = cfg->encap;
  
  	/* Quick sanity checks */
+ 	err = -EPROTONOSUPPORT;
+ 	if (sk->sk_type != SOCK_DGRAM) {
+ 		pr_debug("tunl %hu: fd %d wrong socket type\n",
+ 			 tunnel_id, fd);
+ 		goto err;
+ 	}
  	switch (encap) {
  	case L2TP_ENCAPTYPE_UDP:
- 		err = -EPROTONOSUPPORT;
  		if (sk->sk_protocol != IPPROTO_UDP) {
  			pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
  			       tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
@@@ -1467,7 -1488,6 +1488,6 @@@
  		}
  		break;
  	case L2TP_ENCAPTYPE_IP:
- 		err = -EPROTONOSUPPORT;
  		if (sk->sk_protocol != IPPROTO_L2TP) {
  			pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
  			       tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
@@@ -1507,24 -1527,6 +1527,6 @@@
  	if (cfg != NULL)
  		tunnel->debug = cfg->debug;
  
- #if IS_ENABLED(CONFIG_IPV6)
- 	if (sk->sk_family == PF_INET6) {
- 		struct ipv6_pinfo *np = inet6_sk(sk);
- 
- 		if (ipv6_addr_v4mapped(&np->saddr) &&
- 		    ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
- 			struct inet_sock *inet = inet_sk(sk);
- 
- 			tunnel->v4mapped = true;
- 			inet->inet_saddr = np->saddr.s6_addr32[3];
- 			inet->inet_rcv_saddr = sk->sk_v6_rcv_saddr.s6_addr32[3];
- 			inet->inet_daddr = sk->sk_v6_daddr.s6_addr32[3];
- 		} else {
- 			tunnel->v4mapped = false;
- 		}
- 	}
- #endif
- 
  	/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
  	tunnel->encap = encap;
  	if (encap == L2TP_ENCAPTYPE_UDP) {
@@@ -1787,7 -1789,6 +1789,7 @@@ static struct pernet_operations l2tp_ne
  	.exit = l2tp_exit_net,
  	.id   = &l2tp_net_id,
  	.size = sizeof(struct l2tp_net),
 +	.async = true,
  };
  
  static int __init l2tp_init(void)
diff --combined net/mac80211/debugfs.c
index a75653affbf7,94c7ee9df33b..b5adf3625d16
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@@ -212,7 -212,7 +212,8 @@@ static const char *hw_flag_names[] = 
  	FLAG(REPORTS_LOW_ACK),
  	FLAG(SUPPORTS_TX_FRAG),
  	FLAG(SUPPORTS_TDLS_BUFFER_STA),
 +	FLAG(DEAUTH_NEED_MGD_TX_PREP),
+ 	FLAG(DOESNT_SUPPORT_QOS_NDP),
  #undef FLAG
  };
  
diff --combined net/mac80211/mlme.c
index 0024eff9bb84,5f303abac5ad..fe4aefb06d9f
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@@ -7,7 -7,6 +7,7 @@@
   * Copyright 2007, Michael Wu <flamingice at sourmilk.net>
   * Copyright 2013-2014  Intel Mobile Communications GmbH
   * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
 + * Copyright (C) 2018        Intel Corporation
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -897,7 -896,8 +897,8 @@@ void ieee80211_send_nullfunc(struct iee
  	struct ieee80211_hdr_3addr *nullfunc;
  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  
- 	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, true);
+ 	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif,
+ 		!ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP));
  	if (!skb)
  		return;
  
@@@ -2009,22 -2009,9 +2010,22 @@@ static void ieee80211_set_disassoc(stru
  		ieee80211_flush_queues(local, sdata, true);
  
  	/* deauthenticate/disassociate now */
 -	if (tx || frame_buf)
 +	if (tx || frame_buf) {
 +		struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 +
 +		/*
 +		 * In multi channel scenarios guarantee that the virtual
 +		 * interface is granted immediate airtime to transmit the
 +		 * deauthentication frame by calling mgd_prepare_tx, if the
 +		 * driver requested so.
 +		 */
 +		if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
 +		    !ifmgd->have_beacon)
 +			drv_mgd_prepare_tx(sdata->local, sdata);
 +
  		ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
  					       reason, tx, frame_buf);
 +	}
  
  	/* flush out frame - make sure the deauth was actually sent */
  	if (tx)
@@@ -2165,7 -2152,7 +2166,7 @@@ static void ieee80211_sta_tx_wmm_ac_not
  					   u16 tx_time)
  {
  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 -	u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
 +	u16 tid = ieee80211_get_tid(hdr);
  	int ac = ieee80211_ac_from_tid(tid);
  	struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
  	unsigned long now = jiffies;
diff --combined net/netfilter/nf_tables_api.c
index 8e19c86d1aa6,c4acc7340eb1..fd13d28e4ca7
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@@ -5423,6 -5423,7 +5423,7 @@@ err
  static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
  {
  	cancel_delayed_work_sync(&flowtable->data.gc_work);
+ 	kfree(flowtable->ops);
  	kfree(flowtable->name);
  	flowtable->data.type->free(&flowtable->data);
  	rhashtable_destroy(&flowtable->data.rhashtable);
@@@ -6596,7 -6597,6 +6597,7 @@@ static void __net_exit nf_tables_exit_n
  static struct pernet_operations nf_tables_net_ops = {
  	.init	= nf_tables_init_net,
  	.exit	= nf_tables_exit_net,
 +	.async	= true,
  };
  
  static int __init nf_tables_module_init(void)
diff --combined net/netfilter/x_tables.c
index d9deebe599ec,4aa01c90e9d1..6de1f6a4cb80
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@@ -423,6 -423,36 +423,36 @@@ textify_hooks(char *buf, size_t size, u
  	return buf;
  }
  
+ /**
+  * xt_check_proc_name - check that name is suitable for /proc file creation
+  *
+  * @name: file name candidate
+  * @size: length of buffer
+  *
+  * some x_tables modules wish to create a file in /proc.
+  * This function makes sure that the name is suitable for this
+  * purpose, it checks that name is NUL terminated and isn't a 'special'
+  * name, like "..".
+  *
+  * returns negative number on error or 0 if name is useable.
+  */
+ int xt_check_proc_name(const char *name, unsigned int size)
+ {
+ 	if (name[0] == '\0')
+ 		return -EINVAL;
+ 
+ 	if (strnlen(name, size) == size)
+ 		return -ENAMETOOLONG;
+ 
+ 	if (strcmp(name, ".") == 0 ||
+ 	    strcmp(name, "..") == 0 ||
+ 	    strchr(name, '/'))
+ 		return -EINVAL;
+ 
+ 	return 0;
+ }
+ EXPORT_SYMBOL(xt_check_proc_name);
+ 
  int xt_check_match(struct xt_mtchk_param *par,
  		   unsigned int size, u_int8_t proto, bool inv_proto)
  {
@@@ -1759,7 -1789,6 +1789,7 @@@ static void __net_exit xt_net_exit(stru
  static struct pernet_operations xt_net_ops = {
  	.init = xt_net_init,
  	.exit = xt_net_exit,
 +	.async = true,
  };
  
  static int __init xt_init(void)
diff --combined net/netfilter/xt_hashlimit.c
index db2fe0911740,3360f13dc208..ef65b7a9173e
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@@ -917,8 -917,9 +917,9 @@@ static int hashlimit_mt_check_v1(const 
  	struct hashlimit_cfg3 cfg = {};
  	int ret;
  
- 	if (info->name[sizeof(info->name) - 1] != '\0')
- 		return -EINVAL;
+ 	ret = xt_check_proc_name(info->name, sizeof(info->name));
+ 	if (ret)
+ 		return ret;
  
  	ret = cfg_copy(&cfg, (void *)&info->cfg, 1);
  
@@@ -935,8 -936,9 +936,9 @@@ static int hashlimit_mt_check_v2(const 
  	struct hashlimit_cfg3 cfg = {};
  	int ret;
  
- 	if (info->name[sizeof(info->name) - 1] != '\0')
- 		return -EINVAL;
+ 	ret = xt_check_proc_name(info->name, sizeof(info->name));
+ 	if (ret)
+ 		return ret;
  
  	ret = cfg_copy(&cfg, (void *)&info->cfg, 2);
  
@@@ -950,9 -952,11 +952,11 @@@
  static int hashlimit_mt_check(const struct xt_mtchk_param *par)
  {
  	struct xt_hashlimit_mtinfo3 *info = par->matchinfo;
+ 	int ret;
  
- 	if (info->name[sizeof(info->name) - 1] != '\0')
- 		return -EINVAL;
+ 	ret = xt_check_proc_name(info->name, sizeof(info->name));
+ 	if (ret)
+ 		return ret;
  
  	return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg,
  					 info->name, 3);
@@@ -1345,7 -1349,6 +1349,7 @@@ static struct pernet_operations hashlim
  	.exit	= hashlimit_net_exit,
  	.id	= &hashlimit_net_id,
  	.size	= sizeof(struct hashlimit_net),
 +	.async	= true,
  };
  
  static int __init hashlimit_mt_init(void)
diff --combined net/netfilter/xt_recent.c
index 19efdb757944,81ee1d6543b2..486dd24da78b
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@@ -361,9 -361,9 +361,9 @@@ static int recent_mt_check(const struc
  				    info->hit_count, XT_RECENT_MAX_NSTAMPS - 1);
  		return -EINVAL;
  	}
- 	if (info->name[0] == '\0' ||
- 	    strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
- 		return -EINVAL;
+ 	ret = xt_check_proc_name(info->name, sizeof(info->name));
+ 	if (ret)
+ 		return ret;
  
  	if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot)
  		nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1;
@@@ -687,7 -687,6 +687,7 @@@ static struct pernet_operations recent_
  	.exit	= recent_net_exit,
  	.id	= &recent_net_id,
  	.size	= sizeof(struct recent_net),
 +	.async	= true,
  };
  
  static struct xt_match recent_mt_reg[] __read_mostly = {
diff --combined net/netlink/genetlink.c
index a6f63a5faee7,b9ce82c9440f..af51b8c0a2cb
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@@ -1035,7 -1035,6 +1035,7 @@@ static void __net_exit genl_pernet_exit
  static struct pernet_operations genl_pernet_ops = {
  	.init = genl_pernet_init,
  	.exit = genl_pernet_exit,
 +	.async = true,
  };
  
  static int __init genl_init(void)
@@@ -1107,7 -1106,7 +1107,7 @@@ static int genlmsg_mcast(struct sk_buf
  	if (!err)
  		delivered = true;
  	else if (err != -ESRCH)
- 		goto error;
+ 		return err;
  	return delivered ? 0 : -ESRCH;
   error:
  	kfree_skb(skb);
diff --combined net/sched/act_bpf.c
index da72e0cf2b1f,9d2cabf1dc7e..5cb9b268e8ff
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@@ -272,7 -272,7 +272,7 @@@ static void tcf_bpf_prog_fill_cfg(cons
  
  static int tcf_bpf_init(struct net *net, struct nlattr *nla,
  			struct nlattr *est, struct tc_action **act,
 -			int replace, int bind)
 +			int replace, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, bpf_net_id);
  	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
@@@ -352,7 -352,7 +352,7 @@@
  	return res;
  out:
  	if (res == ACT_P_CREATED)
- 		tcf_idr_cleanup(*act, est);
+ 		tcf_idr_release(*act, bind);
  
  	return ret;
  }
@@@ -367,16 -367,14 +367,16 @@@ static void tcf_bpf_cleanup(struct tc_a
  
  static int tcf_bpf_walker(struct net *net, struct sk_buff *skb,
  			  struct netlink_callback *cb, int type,
 -			  const struct tc_action_ops *ops)
 +			  const struct tc_action_ops *ops,
 +			  struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, bpf_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
 +			  struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, bpf_net_id);
  
@@@ -413,7 -411,6 +413,7 @@@ static struct pernet_operations bpf_net
  	.exit_batch = bpf_exit_net,
  	.id   = &bpf_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int __init bpf_init_module(void)
diff --combined net/sched/act_csum.c
index 1fb1f1f6a555,2a5c8fd860cf..a527e287c086
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@@ -46,7 -46,7 +46,7 @@@ static struct tc_action_ops act_csum_op
  
  static int tcf_csum_init(struct net *net, struct nlattr *nla,
  			 struct nlattr *est, struct tc_action **a, int ovr,
 -			 int bind)
 +			 int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, csum_net_id);
  	struct tcf_csum_params *params_old, *params_new;
@@@ -350,7 -350,7 +350,7 @@@ static int tcf_csum_sctp(struct sk_buf
  {
  	struct sctphdr *sctph;
  
- 	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_SCTP)
+ 	if (skb_is_gso(skb) && skb_is_gso_sctp(skb))
  		return 1;
  
  	sctph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*sctph));
@@@ -626,21 -626,20 +626,22 @@@ static void tcf_csum_cleanup(struct tc_
  	struct tcf_csum_params *params;
  
  	params = rcu_dereference_protected(p->params, 1);
- 	kfree_rcu(params, rcu);
+ 	if (params)
+ 		kfree_rcu(params, rcu);
  }
  
  static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
  			   struct netlink_callback *cb, int type,
 -			   const struct tc_action_ops *ops)
 +			   const struct tc_action_ops *ops,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, csum_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, csum_net_id);
  
@@@ -677,7 -676,6 +678,7 @@@ static struct pernet_operations csum_ne
  	.exit_batch = csum_exit_net,
  	.id   = &csum_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  MODULE_DESCRIPTION("Checksum updating actions");
diff --combined net/sched/act_ipt.c
index 10866717f88e,7e06b9b62613..b5e8565b89c7
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@@ -80,9 -80,12 +80,12 @@@ static void ipt_destroy_target(struct x
  static void tcf_ipt_release(struct tc_action *a)
  {
  	struct tcf_ipt *ipt = to_ipt(a);
- 	ipt_destroy_target(ipt->tcfi_t);
+ 
+ 	if (ipt->tcfi_t) {
+ 		ipt_destroy_target(ipt->tcfi_t);
+ 		kfree(ipt->tcfi_t);
+ 	}
  	kfree(ipt->tcfi_tname);
- 	kfree(ipt->tcfi_t);
  }
  
  static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
@@@ -187,13 -190,13 +190,13 @@@ err2
  	kfree(tname);
  err1:
  	if (ret == ACT_P_CREATED)
- 		tcf_idr_cleanup(*a, est);
+ 		tcf_idr_release(*a, bind);
  	return err;
  }
  
  static int tcf_ipt_init(struct net *net, struct nlattr *nla,
  			struct nlattr *est, struct tc_action **a, int ovr,
 -			int bind)
 +			int bind, struct netlink_ext_ack *extack)
  {
  	return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
  			      bind);
@@@ -201,7 -204,7 +204,7 @@@
  
  static int tcf_xt_init(struct net *net, struct nlattr *nla,
  		       struct nlattr *est, struct tc_action **a, int ovr,
 -		       int bind)
 +		       int bind, struct netlink_ext_ack *extack)
  {
  	return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
  			      bind);
@@@ -303,16 -306,14 +306,16 @@@ nla_put_failure
  
  static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
  			  struct netlink_callback *cb, int type,
 -			  const struct tc_action_ops *ops)
 +			  const struct tc_action_ops *ops,
 +			  struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, ipt_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index,
 +			  struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, ipt_net_id);
  
@@@ -349,21 -350,18 +352,21 @@@ static struct pernet_operations ipt_net
  	.exit_batch = ipt_exit_net,
  	.id   = &ipt_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
  			 struct netlink_callback *cb, int type,
 -			 const struct tc_action_ops *ops)
 +			 const struct tc_action_ops *ops,
 +			 struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, xt_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index,
 +			 struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, xt_net_id);
  
@@@ -400,7 -398,6 +403,7 @@@ static struct pernet_operations xt_net_
  	.exit_batch = xt_exit_net,
  	.id   = &xt_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
diff --combined net/sched/act_pedit.c
index 5e8cc8f63acd,fef08835f26d..f392ccaaa0d8
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@@ -132,7 -132,7 +132,7 @@@ static int tcf_pedit_key_ex_dump(struc
  
  static int tcf_pedit_init(struct net *net, struct nlattr *nla,
  			  struct nlattr *est, struct tc_action **a,
 -			  int ovr, int bind)
 +			  int ovr, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, pedit_net_id);
  	struct nlattr *tb[TCA_PEDIT_MAX + 1];
@@@ -176,7 -176,7 +176,7 @@@
  		p = to_pedit(*a);
  		keys = kmalloc(ksize, GFP_KERNEL);
  		if (keys == NULL) {
- 			tcf_idr_cleanup(*a, est);
+ 			tcf_idr_release(*a, bind);
  			kfree(keys_ex);
  			return -ENOMEM;
  		}
@@@ -419,16 -419,14 +419,16 @@@ nla_put_failure
  
  static int tcf_pedit_walker(struct net *net, struct sk_buff *skb,
  			    struct netlink_callback *cb, int type,
 -			    const struct tc_action_ops *ops)
 +			    const struct tc_action_ops *ops,
 +			    struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, pedit_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index,
 +			    struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, pedit_net_id);
  
@@@ -465,7 -463,6 +465,7 @@@ static struct pernet_operations pedit_n
  	.exit_batch = pedit_exit_net,
  	.id   = &pedit_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
diff --combined net/sched/act_police.c
index 51fe4fe343f7,faebf82b99f1..7081ec75e696
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@@ -58,12 -58,11 +58,12 @@@ static struct tc_action_ops act_police_
  
  static int tcf_act_police_walker(struct net *net, struct sk_buff *skb,
  				 struct netlink_callback *cb, int type,
 -				 const struct tc_action_ops *ops)
 +				 const struct tc_action_ops *ops,
 +				 struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, police_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
  static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
@@@ -75,8 -74,7 +75,8 @@@
  
  static int tcf_act_police_init(struct net *net, struct nlattr *nla,
  			       struct nlattr *est, struct tc_action **a,
 -			       int ovr, int bind)
 +			       int ovr, int bind,
 +			       struct netlink_ext_ack *extack)
  {
  	int ret = 0, err;
  	struct nlattr *tb[TCA_POLICE_MAX + 1];
@@@ -196,7 -194,7 +196,7 @@@ failure
  	qdisc_put_rtab(P_tab);
  	qdisc_put_rtab(R_tab);
  	if (ret == ACT_P_CREATED)
- 		tcf_idr_cleanup(*a, est);
+ 		tcf_idr_release(*a, bind);
  	return err;
  }
  
@@@ -306,8 -304,7 +306,8 @@@ nla_put_failure
  	return -1;
  }
  
 -static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_police_search(struct net *net, struct tc_action **a, u32 index,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, police_net_id);
  
@@@ -347,7 -344,6 +347,7 @@@ static struct pernet_operations police_
  	.exit_batch = police_exit_net,
  	.id   = &police_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int __init police_init_module(void)
diff --combined net/sched/act_sample.c
index 238dfd27e995,74c5d7e6a0fa..3a89f98f17e6
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@@ -37,7 -37,7 +37,7 @@@ static const struct nla_policy sample_p
  
  static int tcf_sample_init(struct net *net, struct nlattr *nla,
  			   struct nlattr *est, struct tc_action **a, int ovr,
 -			   int bind)
 +			   int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, sample_net_id);
  	struct nlattr *tb[TCA_SAMPLE_MAX + 1];
@@@ -103,7 -103,8 +103,8 @@@ static void tcf_sample_cleanup(struct t
  
  	psample_group = rtnl_dereference(s->psample_group);
  	RCU_INIT_POINTER(s->psample_group, NULL);
- 	psample_group_put(psample_group);
+ 	if (psample_group)
+ 		psample_group_put(psample_group);
  }
  
  static bool tcf_sample_dev_ok_push(struct net_device *dev)
@@@ -202,16 -203,14 +203,16 @@@ nla_put_failure
  
  static int tcf_sample_walker(struct net *net, struct sk_buff *skb,
  			     struct netlink_callback *cb, int type,
 -			     const struct tc_action_ops *ops)
 +			     const struct tc_action_ops *ops,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, sample_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, sample_net_id);
  
@@@ -248,7 -247,6 +249,7 @@@ static struct pernet_operations sample_
  	.exit_batch = sample_exit_net,
  	.id   = &sample_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int __init sample_init_module(void)
diff --combined net/sched/act_simple.c
index 91816d73f3f3,b1f38063ada0..e84768ae610a
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@@ -79,7 -79,7 +79,7 @@@ static const struct nla_policy simple_p
  
  static int tcf_simp_init(struct net *net, struct nlattr *nla,
  			 struct nlattr *est, struct tc_action **a,
 -			 int ovr, int bind)
 +			 int ovr, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, simp_net_id);
  	struct nlattr *tb[TCA_DEF_MAX + 1];
@@@ -121,7 -121,7 +121,7 @@@
  		d = to_defact(*a);
  		ret = alloc_defdata(d, defdata);
  		if (ret < 0) {
- 			tcf_idr_cleanup(*a, est);
+ 			tcf_idr_release(*a, bind);
  			return ret;
  		}
  		d->tcf_action = parm->action;
@@@ -170,16 -170,14 +170,16 @@@ nla_put_failure
  
  static int tcf_simp_walker(struct net *net, struct sk_buff *skb,
  			   struct netlink_callback *cb, int type,
 -			   const struct tc_action_ops *ops)
 +			   const struct tc_action_ops *ops,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, simp_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, simp_net_id);
  
@@@ -216,7 -214,6 +216,7 @@@ static struct pernet_operations simp_ne
  	.exit_batch = simp_exit_net,
  	.id   = &simp_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  MODULE_AUTHOR("Jamal Hadi Salim(2005)");
diff --combined net/sched/act_skbmod.c
index febec75f4f7a,7b0700f52b50..142a996ac776
--- a/net/sched/act_skbmod.c
+++ b/net/sched/act_skbmod.c
@@@ -84,7 -84,7 +84,7 @@@ static const struct nla_policy skbmod_p
  
  static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
  			   struct nlattr *est, struct tc_action **a,
 -			   int ovr, int bind)
 +			   int ovr, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, skbmod_net_id);
  	struct nlattr *tb[TCA_SKBMOD_MAX + 1];
@@@ -152,7 -152,7 +152,7 @@@
  	ASSERT_RTNL();
  	p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);
  	if (unlikely(!p)) {
- 		if (ovr)
+ 		if (ret == ACT_P_CREATED)
  			tcf_idr_release(*a, bind);
  		return -ENOMEM;
  	}
@@@ -190,7 -190,8 +190,8 @@@ static void tcf_skbmod_cleanup(struct t
  	struct tcf_skbmod_params  *p;
  
  	p = rcu_dereference_protected(d->skbmod_p, 1);
- 	kfree_rcu(p, rcu);
+ 	if (p)
+ 		kfree_rcu(p, rcu);
  }
  
  static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
@@@ -232,16 -233,14 +233,16 @@@ nla_put_failure
  
  static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb,
  			     struct netlink_callback *cb, int type,
 -			     const struct tc_action_ops *ops)
 +			     const struct tc_action_ops *ops,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, skbmod_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, skbmod_net_id);
  
@@@ -278,7 -277,6 +279,7 @@@ static struct pernet_operations skbmod_
  	.exit_batch = skbmod_exit_net,
  	.id   = &skbmod_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  MODULE_AUTHOR("Jamal Hadi Salim, <jhs at mojatatu.com>");
diff --combined net/sched/act_tunnel_key.c
index 9169b7e78ada,1281ca463727..a1c8dd406a04
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@@ -70,7 -70,7 +70,7 @@@ static const struct nla_policy tunnel_k
  
  static int tunnel_key_init(struct net *net, struct nlattr *nla,
  			   struct nlattr *est, struct tc_action **a,
 -			   int ovr, int bind)
 +			   int ovr, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
  	struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
@@@ -153,6 -153,7 +153,7 @@@
  		metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
  		break;
  	default:
+ 		ret = -EINVAL;
  		goto err_out;
  	}
  
@@@ -207,11 -208,12 +208,12 @@@ static void tunnel_key_release(struct t
  	struct tcf_tunnel_key_params *params;
  
  	params = rcu_dereference_protected(t->params, 1);
+ 	if (params) {
+ 		if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ 			dst_release(&params->tcft_enc_metadata->dst);
  
- 	if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
- 		dst_release(&params->tcft_enc_metadata->dst);
- 
- 	kfree_rcu(params, rcu);
+ 		kfree_rcu(params, rcu);
+ 	}
  }
  
  static int tunnel_key_dump_addresses(struct sk_buff *skb,
@@@ -291,16 -293,14 +293,16 @@@ nla_put_failure
  
  static int tunnel_key_walker(struct net *net, struct sk_buff *skb,
  			     struct netlink_callback *cb, int type,
 -			     const struct tc_action_ops *ops)
 +			     const struct tc_action_ops *ops,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)
 +static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
 +			     struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
  
@@@ -337,7 -337,6 +339,7 @@@ static struct pernet_operations tunnel_
  	.exit_batch = tunnel_key_exit_net,
  	.id   = &tunnel_key_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int __init tunnel_key_init_module(void)
diff --combined net/sched/act_vlan.c
index c2ee7fd51cc9,c49cb61adedf..4595391c2129
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@@ -109,7 -109,7 +109,7 @@@ static const struct nla_policy vlan_pol
  
  static int tcf_vlan_init(struct net *net, struct nlattr *nla,
  			 struct nlattr *est, struct tc_action **a,
 -			 int ovr, int bind)
 +			 int ovr, int bind, struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, vlan_net_id);
  	struct nlattr *tb[TCA_VLAN_MAX + 1];
@@@ -195,7 -195,7 +195,7 @@@
  	ASSERT_RTNL();
  	p = kzalloc(sizeof(*p), GFP_KERNEL);
  	if (!p) {
- 		if (ovr)
+ 		if (ret == ACT_P_CREATED)
  			tcf_idr_release(*a, bind);
  		return -ENOMEM;
  	}
@@@ -225,7 -225,8 +225,8 @@@ static void tcf_vlan_cleanup(struct tc_
  	struct tcf_vlan_params *p;
  
  	p = rcu_dereference_protected(v->vlan_p, 1);
- 	kfree_rcu(p, rcu);
+ 	if (p)
+ 		kfree_rcu(p, rcu);
  }
  
  static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
@@@ -267,16 -268,14 +268,16 @@@ nla_put_failure
  
  static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
  			   struct netlink_callback *cb, int type,
 -			   const struct tc_action_ops *ops)
 +			   const struct tc_action_ops *ops,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, vlan_net_id);
  
 -	return tcf_generic_walker(tn, skb, cb, type, ops);
 +	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
  }
  
 -static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)
 +static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
 +			   struct netlink_ext_ack *extack)
  {
  	struct tc_action_net *tn = net_generic(net, vlan_net_id);
  
@@@ -313,7 -312,6 +314,7 @@@ static struct pernet_operations vlan_ne
  	.exit_batch = vlan_exit_net,
  	.id   = &vlan_net_id,
  	.size = sizeof(struct tc_action_net),
 +	.async = true,
  };
  
  static int __init vlan_init_module(void)
diff --combined net/smc/af_smc.c
index 86913eb5cfa0,1e0d780855c3..5f8046c62d90
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@@ -7,11 -7,13 +7,11 @@@
   *  applicable with RoCE-cards only
   *
   *  Initial restrictions:
 - *    - non-blocking connect postponed
 - *    - IPv6 support postponed
   *    - support for alternate links postponed
   *    - partial support for non-blocking sockets only
   *    - support for urgent data postponed
   *
 - *  Copyright IBM Corp. 2016
 + *  Copyright IBM Corp. 2016, 2018
   *
   *  Author(s):  Ursula Braun <ubraun at linux.vnet.ibm.com>
   *              based on prototype from Frank Blaschka
@@@ -22,6 -24,7 +22,6 @@@
  
  #include <linux/module.h>
  #include <linux/socket.h>
 -#include <linux/inetdevice.h>
  #include <linux/workqueue.h>
  #include <linux/in.h>
  #include <linux/sched/signal.h>
@@@ -63,10 -66,6 +63,10 @@@ static struct smc_hashinfo smc_v4_hashi
  	.lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
  };
  
 +static struct smc_hashinfo smc_v6_hashinfo = {
 +	.lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
 +};
 +
  int smc_hash_sk(struct sock *sk)
  {
  	struct smc_hashinfo *h = sk->sk_prot->h.smc_hash;
@@@ -106,18 -105,6 +106,18 @@@ struct proto smc_proto = 
  };
  EXPORT_SYMBOL_GPL(smc_proto);
  
 +struct proto smc_proto6 = {
 +	.name		= "SMC6",
 +	.owner		= THIS_MODULE,
 +	.keepalive	= smc_set_keepalive,
 +	.hash		= smc_hash_sk,
 +	.unhash		= smc_unhash_sk,
 +	.obj_size	= sizeof(struct smc_sock),
 +	.h.smc_hash	= &smc_v6_hashinfo,
 +	.slab_flags	= SLAB_TYPESAFE_BY_RCU,
 +};
 +EXPORT_SYMBOL_GPL(smc_proto6);
 +
  static int smc_release(struct socket *sock)
  {
  	struct sock *sk = sock->sk;
@@@ -174,22 -161,19 +174,22 @@@ static void smc_destruct(struct sock *s
  	sk_refcnt_debug_dec(sk);
  }
  
 -static struct sock *smc_sock_alloc(struct net *net, struct socket *sock)
 +static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
 +				   int protocol)
  {
  	struct smc_sock *smc;
 +	struct proto *prot;
  	struct sock *sk;
  
 -	sk = sk_alloc(net, PF_SMC, GFP_KERNEL, &smc_proto, 0);
 +	prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
 +	sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
  	if (!sk)
  		return NULL;
  
  	sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
  	sk->sk_state = SMC_INIT;
  	sk->sk_destruct = smc_destruct;
 -	sk->sk_protocol = SMCPROTO_SMC;
 +	sk->sk_protocol = protocol;
  	smc = smc_sk(sk);
  	INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
  	INIT_LIST_HEAD(&smc->accept_q);
@@@ -216,13 -200,10 +216,13 @@@ static int smc_bind(struct socket *sock
  		goto out;
  
  	rc = -EAFNOSUPPORT;
 +	if (addr->sin_family != AF_INET &&
 +	    addr->sin_family != AF_INET6 &&
 +	    addr->sin_family != AF_UNSPEC)
 +		goto out;
  	/* accept AF_UNSPEC (mapped to AF_INET) only if s_addr is INADDR_ANY */
 -	if ((addr->sin_family != AF_INET) &&
 -	    ((addr->sin_family != AF_UNSPEC) ||
 -	     (addr->sin_addr.s_addr != htonl(INADDR_ANY))))
 +	if (addr->sin_family == AF_UNSPEC &&
 +	    addr->sin_addr.s_addr != htonl(INADDR_ANY))
  		goto out;
  
  	lock_sock(sk);
@@@ -292,7 -273,47 +292,7 @@@ static void smc_copy_sock_settings_to_s
  	smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
  }
  
 -/* determine subnet and mask of internal TCP socket */
 -int smc_netinfo_by_tcpsk(struct socket *clcsock,
 -			 __be32 *subnet, u8 *prefix_len)
 -{
 -	struct dst_entry *dst = sk_dst_get(clcsock->sk);
 -	struct in_device *in_dev;
 -	struct sockaddr_in addr;
 -	int rc = -ENOENT;
 -	int len;
 -
 -	if (!dst) {
 -		rc = -ENOTCONN;
 -		goto out;
 -	}
 -	if (!dst->dev) {
 -		rc = -ENODEV;
 -		goto out_rel;
 -	}
 -
 -	/* get address to which the internal TCP socket is bound */
 -	kernel_getsockname(clcsock, (struct sockaddr *)&addr, &len);
 -	/* analyze IPv4 specific data of net_device belonging to TCP socket */
 -	rcu_read_lock();
 -	in_dev = __in_dev_get_rcu(dst->dev);
 -	for_ifa(in_dev) {
 -		if (!inet_ifa_match(addr.sin_addr.s_addr, ifa))
 -			continue;
 -		*prefix_len = inet_mask_len(ifa->ifa_mask);
 -		*subnet = ifa->ifa_address & ifa->ifa_mask;
 -		rc = 0;
 -		break;
 -	} endfor_ifa(in_dev);
 -	rcu_read_unlock();
 -
 -out_rel:
 -	dst_release(dst);
 -out:
 -	return rc;
 -}
 -
 -static int smc_clnt_conf_first_link(struct smc_sock *smc, union ib_gid *gid)
 +static int smc_clnt_conf_first_link(struct smc_sock *smc)
  {
  	struct smc_link_group *lgr = smc->conn.lgr;
  	struct smc_link *link;
@@@ -312,9 -333,6 +312,9 @@@
  		return rc;
  	}
  
 +	if (link->llc_confirm_rc)
 +		return SMC_CLC_DECL_RMBE_EC;
 +
  	rc = smc_ib_modify_qp_rts(link);
  	if (rc)
  		return SMC_CLC_DECL_INTERR;
@@@ -329,33 -347,11 +329,33 @@@
  	/* send CONFIRM LINK response over RoCE fabric */
  	rc = smc_llc_send_confirm_link(link,
  				       link->smcibdev->mac[link->ibport - 1],
 -				       gid, SMC_LLC_RESP);
 +				       &link->smcibdev->gid[link->ibport - 1],
 +				       SMC_LLC_RESP);
  	if (rc < 0)
  		return SMC_CLC_DECL_TCL;
  
 -	return rc;
 +	/* receive ADD LINK request from server over RoCE fabric */
 +	rest = wait_for_completion_interruptible_timeout(&link->llc_add,
 +							 SMC_LLC_WAIT_TIME);
 +	if (rest <= 0) {
 +		struct smc_clc_msg_decline dclc;
 +
 +		rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
 +				      SMC_CLC_DECLINE);
 +		return rc;
 +	}
 +
 +	/* send add link reject message, only one link supported for now */
 +	rc = smc_llc_send_add_link(link,
 +				   link->smcibdev->mac[link->ibport - 1],
 +				   &link->smcibdev->gid[link->ibport - 1],
 +				   SMC_LLC_RESP);
 +	if (rc < 0)
 +		return SMC_CLC_DECL_TCL;
 +
 +	link->state = SMC_LNK_ACTIVE;
 +
 +	return 0;
  }
  
  static void smc_conn_save_peer_info(struct smc_sock *smc,
@@@ -377,9 -373,19 +377,9 @@@ static void smc_link_save_peer_info(str
  	link->peer_mtu = clc->qp_mtu;
  }
  
 -static void smc_lgr_forget(struct smc_link_group *lgr)
 -{
 -	spin_lock_bh(&smc_lgr_list.lock);
 -	/* do not use this link group for new connections */
 -	if (!list_empty(&lgr->list))
 -		list_del_init(&lgr->list);
 -	spin_unlock_bh(&smc_lgr_list.lock);
 -}
 -
  /* setup for RDMA connection of client */
  static int smc_connect_rdma(struct smc_sock *smc)
  {
 -	struct sockaddr_in *inaddr = (struct sockaddr_in *)smc->addr;
  	struct smc_clc_msg_accept_confirm aclc;
  	int local_contact = SMC_FIRST_CONTACT;
  	struct smc_ib_device *smcibdev;
@@@ -433,8 -439,8 +433,8 @@@
  
  	srv_first_contact = aclc.hdr.flag;
  	mutex_lock(&smc_create_lgr_pending);
 -	local_contact = smc_conn_create(smc, inaddr->sin_addr.s_addr, smcibdev,
 -					ibport, &aclc.lcl, srv_first_contact);
 +	local_contact = smc_conn_create(smc, smcibdev, ibport, &aclc.lcl,
 +					srv_first_contact);
  	if (local_contact < 0) {
  		rc = local_contact;
  		if (rc == -ENOMEM)
@@@ -493,7 -499,8 +493,7 @@@
  
  	if (local_contact == SMC_FIRST_CONTACT) {
  		/* QP confirmation over RoCE fabric */
 -		reason_code = smc_clnt_conf_first_link(
 -			smc, &smcibdev->gid[ibport - 1]);
 +		reason_code = smc_clnt_conf_first_link(smc);
  		if (reason_code < 0) {
  			rc = reason_code;
  			goto out_err_unlock;
@@@ -550,8 -557,9 +550,8 @@@ static int smc_connect(struct socket *s
  	/* separate smc parameter checking to be safe */
  	if (alen < sizeof(addr->sa_family))
  		goto out_err;
 -	if (addr->sa_family != AF_INET)
 +	if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
  		goto out_err;
 -	smc->addr = addr;	/* needed for nonblocking connect */
  
  	lock_sock(sk);
  	switch (sk->sk_state) {
@@@ -592,7 -600,7 +592,7 @@@ static int smc_clcsock_accept(struct sm
  	int rc;
  
  	release_sock(lsk);
 -	new_sk = smc_sock_alloc(sock_net(lsk), NULL);
 +	new_sk = smc_sock_alloc(sock_net(lsk), NULL, lsk->sk_protocol);
  	if (!new_sk) {
  		rc = -ENOMEM;
  		lsk->sk_err = ENOMEM;
@@@ -741,34 -749,9 +741,34 @@@ static int smc_serv_conf_first_link(str
  
  		rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
  				      SMC_CLC_DECLINE);
 +		return rc;
  	}
  
 -	return rc;
 +	if (link->llc_confirm_resp_rc)
 +		return SMC_CLC_DECL_RMBE_EC;
 +
 +	/* send ADD LINK request to client over the RoCE fabric */
 +	rc = smc_llc_send_add_link(link,
 +				   link->smcibdev->mac[link->ibport - 1],
 +				   &link->smcibdev->gid[link->ibport - 1],
 +				   SMC_LLC_REQ);
 +	if (rc < 0)
 +		return SMC_CLC_DECL_TCL;
 +
 +	/* receive ADD LINK response from client over the RoCE fabric */
 +	rest = wait_for_completion_interruptible_timeout(&link->llc_add_resp,
 +							 SMC_LLC_WAIT_TIME);
 +	if (rest <= 0) {
 +		struct smc_clc_msg_decline dclc;
 +
 +		rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
 +				      SMC_CLC_DECLINE);
 +		return rc;
 +	}
 +
 +	link->state = SMC_LNK_ACTIVE;
 +
 +	return 0;
  }
  
  /* setup for RDMA connection of server */
@@@ -784,10 -767,13 +784,10 @@@ static void smc_listen_work(struct work
  	struct sock *newsmcsk = &new_smc->sk;
  	struct smc_clc_msg_proposal *pclc;
  	struct smc_ib_device *smcibdev;
 -	struct sockaddr_in peeraddr;
  	u8 buf[SMC_CLC_MAX_LEN];
  	struct smc_link *link;
  	int reason_code = 0;
 -	int rc = 0, len;
 -	__be32 subnet;
 -	u8 prefix_len;
 +	int rc = 0;
  	u8 ibport;
  
  	/* check if peer is smc capable */
@@@ -822,19 -808,28 +822,19 @@@
  		goto decline_rdma;
  	}
  
 -	/* determine subnet and mask from internal TCP socket */
 -	rc = smc_netinfo_by_tcpsk(newclcsock, &subnet, &prefix_len);
 -	if (rc) {
 -		reason_code = SMC_CLC_DECL_CNFERR; /* configuration error */
 -		goto decline_rdma;
 -	}
 -
  	pclc = (struct smc_clc_msg_proposal *)&buf;
  	pclc_prfx = smc_clc_proposal_get_prefix(pclc);
 -	if (pclc_prfx->outgoing_subnet != subnet ||
 -	    pclc_prfx->prefix_len != prefix_len) {
 +
 +	rc = smc_clc_prfx_match(newclcsock, pclc_prfx);
 +	if (rc) {
  		reason_code = SMC_CLC_DECL_CNFERR; /* configuration error */
  		goto decline_rdma;
  	}
  
 -	/* get address of the peer connected to the internal TCP socket */
 -	kernel_getpeername(newclcsock, (struct sockaddr *)&peeraddr, &len);
 -
  	/* allocate connection / link group */
  	mutex_lock(&smc_create_lgr_pending);
 -	local_contact = smc_conn_create(new_smc, peeraddr.sin_addr.s_addr,
 -					smcibdev, ibport, &pclc->lcl, 0);
 +	local_contact = smc_conn_create(new_smc, smcibdev, ibport, &pclc->lcl,
 +					0);
  	if (local_contact < 0) {
  		rc = local_contact;
  		if (rc == -ENOMEM)
@@@ -983,10 -978,6 +983,6 @@@ out
  		lsmc->clcsock = NULL;
  	}
  	release_sock(lsk);
- 	/* no more listening, wake up smc_close_wait_listen_clcsock and
- 	 * accept
- 	 */
- 	lsk->sk_state_change(lsk);
  	sock_put(&lsmc->sk); /* sock_hold in smc_listen */
  }
  
@@@ -1080,7 -1071,7 +1076,7 @@@ out
  }
  
  static int smc_getname(struct socket *sock, struct sockaddr *addr,
 -		       int *len, int peer)
 +		       int peer)
  {
  	struct smc_sock *smc;
  
@@@ -1090,7 -1081,7 +1086,7 @@@
  
  	smc = smc_sk(sock->sk);
  
 -	return smc->clcsock->ops->getname(smc->clcsock, addr, len, peer);
 +	return smc->clcsock->ops->getname(smc->clcsock, addr, peer);
  }
  
  static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
@@@ -1388,7 -1379,6 +1384,7 @@@ static const struct proto_ops smc_sock_
  static int smc_create(struct net *net, struct socket *sock, int protocol,
  		      int kern)
  {
 +	int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET;
  	struct smc_sock *smc;
  	struct sock *sk;
  	int rc;
@@@ -1398,20 -1388,20 +1394,20 @@@
  		goto out;
  
  	rc = -EPROTONOSUPPORT;
 -	if ((protocol != IPPROTO_IP) && (protocol != IPPROTO_TCP))
 +	if (protocol != SMCPROTO_SMC && protocol != SMCPROTO_SMC6)
  		goto out;
  
  	rc = -ENOBUFS;
  	sock->ops = &smc_sock_ops;
 -	sk = smc_sock_alloc(net, sock);
 +	sk = smc_sock_alloc(net, sock, protocol);
  	if (!sk)
  		goto out;
  
  	/* create internal TCP socket for CLC handshake and fallback */
  	smc = smc_sk(sk);
  	smc->use_fallback = false; /* assume rdma capability first */
 -	rc = sock_create_kern(net, PF_INET, SOCK_STREAM,
 -			      IPPROTO_TCP, &smc->clcsock);
 +	rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
 +			      &smc->clcsock);
  	if (rc) {
  		sk_common_release(sk);
  		goto out;
@@@ -1451,23 -1441,16 +1447,23 @@@ static int __init smc_init(void
  
  	rc = proto_register(&smc_proto, 1);
  	if (rc) {
 -		pr_err("%s: proto_register fails with %d\n", __func__, rc);
 +		pr_err("%s: proto_register(v4) fails with %d\n", __func__, rc);
  		goto out_pnet;
  	}
  
 +	rc = proto_register(&smc_proto6, 1);
 +	if (rc) {
 +		pr_err("%s: proto_register(v6) fails with %d\n", __func__, rc);
 +		goto out_proto;
 +	}
 +
  	rc = sock_register(&smc_sock_family_ops);
  	if (rc) {
  		pr_err("%s: sock_register fails with %d\n", __func__, rc);
 -		goto out_proto;
 +		goto out_proto6;
  	}
  	INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
 +	INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
  
  	rc = smc_ib_register_client();
  	if (rc) {
@@@ -1480,8 -1463,6 +1476,8 @@@
  
  out_sock:
  	sock_unregister(PF_SMC);
 +out_proto6:
 +	proto_unregister(&smc_proto6);
  out_proto:
  	proto_unregister(&smc_proto);
  out_pnet:
@@@ -1500,13 -1481,11 +1496,13 @@@ static void __exit smc_exit(void
  	spin_unlock_bh(&smc_lgr_list.lock);
  	list_for_each_entry_safe(lgr, lg, &lgr_freeing_list, list) {
  		list_del_init(&lgr->list);
 +		cancel_delayed_work_sync(&lgr->free_work);
  		smc_lgr_free(lgr); /* free link group */
  	}
  	static_branch_disable(&tcp_have_smc);
  	smc_ib_unregister_client();
  	sock_unregister(PF_SMC);
 +	proto_unregister(&smc_proto6);
  	proto_unregister(&smc_proto);
  	smc_pnet_exit();
  }
diff --combined net/socket.c
index d9a1ac233b35,08847c3b8c39..3d1948d27a25
--- a/net/socket.c
+++ b/net/socket.c
@@@ -104,6 -104,7 +104,6 @@@
  #include <linux/ipv6_route.h>
  #include <linux/route.h>
  #include <linux/sockios.h>
 -#include <linux/atalk.h>
  #include <net/busy_poll.h>
  #include <linux/errqueue.h>
  
@@@ -233,7 -234,7 +233,7 @@@ static int move_addr_to_user(struct soc
  	return __put_user(klen, ulen);
  }
  
 -static struct kmem_cache *sock_inode_cachep __read_mostly;
 +static struct kmem_cache *sock_inode_cachep __ro_after_init;
  
  static struct inode *sock_alloc_inode(struct super_block *sb)
  {
@@@ -990,11 -991,10 +990,11 @@@ static long sock_do_ioctl(struct net *n
   *	what to do with it - that's up to the protocol still.
   */
  
 -static struct ns_common *get_net_ns(struct ns_common *ns)
 +struct ns_common *get_net_ns(struct ns_common *ns)
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
 +EXPORT_SYMBOL_GPL(get_net_ns);
  
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
@@@ -1573,9 -1573,8 +1573,9 @@@ SYSCALL_DEFINE4(accept4, int, fd, struc
  		goto out_fd;
  
  	if (upeer_sockaddr) {
 -		if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
 -					  &len, 2) < 0) {
 +		len = newsock->ops->getname(newsock,
 +					(struct sockaddr *)&address, 2);
 +		if (len < 0) {
  			err = -ECONNABORTED;
  			goto out_fd;
  		}
@@@ -1655,7 -1654,7 +1655,7 @@@ SYSCALL_DEFINE3(getsockname, int, fd, s
  {
  	struct socket *sock;
  	struct sockaddr_storage address;
 -	int len, err, fput_needed;
 +	int err, fput_needed;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
@@@ -1665,11 -1664,10 +1665,11 @@@
  	if (err)
  		goto out_put;
  
 -	err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
 -	if (err)
 +	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
 +	if (err < 0)
  		goto out_put;
 -	err = move_addr_to_user(&address, len, usockaddr, usockaddr_len);
 +        /* "err" is actually length in this case */
 +	err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
  
  out_put:
  	fput_light(sock->file, fput_needed);
@@@ -1687,7 -1685,7 +1687,7 @@@ SYSCALL_DEFINE3(getpeername, int, fd, s
  {
  	struct socket *sock;
  	struct sockaddr_storage address;
 -	int len, err, fput_needed;
 +	int err, fput_needed;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
@@@ -1697,10 -1695,11 +1697,10 @@@
  			return err;
  		}
  
 -		err =
 -		    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
 -				       1);
 -		if (!err)
 -			err = move_addr_to_user(&address, len, usockaddr,
 +		err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
 +		if (err >= 0)
 +			/* "err" is actually length in this case */
 +			err = move_addr_to_user(&address, err, usockaddr,
  						usockaddr_len);
  		fput_light(sock->file, fput_needed);
  	}
@@@ -2289,12 -2288,10 +2289,12 @@@ int __sys_recvmmsg(int fd, struct mmsgh
  	if (!sock)
  		return err;
  
 -	err = sock_error(sock->sk);
 -	if (err) {
 -		datagrams = err;
 -		goto out_put;
 +	if (likely(!(flags & MSG_ERRQUEUE))) {
 +		err = sock_error(sock->sk);
 +		if (err) {
 +			datagrams = err;
 +			goto out_put;
 +		}
  	}
  
  	entry = mmsg;
@@@ -2590,6 -2587,11 +2590,11 @@@ void sock_unregister(int family
  }
  EXPORT_SYMBOL(sock_unregister);
  
+ bool sock_is_registered(int family)
+ {
+ 	return family < NPROTO && rcu_access_pointer(net_families[family]);
+ }
+ 
  static int __init sock_init(void)
  {
  	int err;
@@@ -3169,15 -3171,17 +3174,15 @@@ int kernel_connect(struct socket *sock
  }
  EXPORT_SYMBOL(kernel_connect);
  
 -int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
 -			 int *addrlen)
 +int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
  {
 -	return sock->ops->getname(sock, addr, addrlen, 0);
 +	return sock->ops->getname(sock, addr, 0);
  }
  EXPORT_SYMBOL(kernel_getsockname);
  
 -int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
 -			 int *addrlen)
 +int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
  {
 -	return sock->ops->getname(sock, addr, addrlen, 1);
 +	return sock->ops->getname(sock, addr, 1);
  }
  EXPORT_SYMBOL(kernel_getpeername);
  
diff --combined net/xfrm/xfrm_policy.c
index 77d9d1ab05ce,625b3fca5704..cb3bb9ae4407
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@@ -1458,10 -1458,13 +1458,13 @@@ xfrm_tmpl_resolve(struct xfrm_policy **
  static int xfrm_get_tos(const struct flowi *fl, int family)
  {
  	const struct xfrm_policy_afinfo *afinfo;
- 	int tos = 0;
+ 	int tos;
  
  	afinfo = xfrm_policy_get_afinfo(family);
- 	tos = afinfo ? afinfo->get_tos(fl) : 0;
+ 	if (!afinfo)
+ 		return 0;
+ 
+ 	tos = afinfo->get_tos(fl);
  
  	rcu_read_unlock();
  
@@@ -1891,7 -1894,7 +1894,7 @@@ static void xfrm_policy_queue_process(s
  	spin_unlock(&pq->hold_queue.lock);
  
  	dst_hold(xfrm_dst_path(dst));
- 	dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0);
+ 	dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, XFRM_LOOKUP_QUEUE);
  	if (IS_ERR(dst))
  		goto purge_queue;
  
@@@ -2729,14 -2732,14 +2732,14 @@@ static const void *xfrm_get_dst_nexthop
  	while (dst->xfrm) {
  		const struct xfrm_state *xfrm = dst->xfrm;
  
+ 		dst = xfrm_dst_child(dst);
+ 
  		if (xfrm->props.mode == XFRM_MODE_TRANSPORT)
  			continue;
  		if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR)
  			daddr = xfrm->coaddr;
  		else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
  			daddr = &xfrm->id.daddr;
- 
- 		dst = xfrm_dst_child(dst);
  	}
  	return daddr;
  }
@@@ -2982,7 -2985,6 +2985,7 @@@ static void __net_exit xfrm_net_exit(st
  static struct pernet_operations __net_initdata xfrm_net_ops = {
  	.init = xfrm_net_init,
  	.exit = xfrm_net_exit,
 +	.async = true,
  };
  
  void __init xfrm_init(void)
diff --combined net/xfrm/xfrm_user.c
index aff2e84ec761,080035f056d9..e92b8c019c88
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@@ -121,22 -121,17 +121,17 @@@ static inline int verify_replay(struct 
  	struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
  	struct xfrm_replay_state_esn *rs;
  
- 	if (p->flags & XFRM_STATE_ESN) {
- 		if (!rt)
- 			return -EINVAL;
- 
- 		rs = nla_data(rt);
+ 	if (!rt)
+ 		return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0;
  
- 		if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
- 			return -EINVAL;
+ 	rs = nla_data(rt);
  
- 		if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) &&
- 		    nla_len(rt) != sizeof(*rs))
- 			return -EINVAL;
- 	}
+ 	if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+ 		return -EINVAL;
  
- 	if (!rt)
- 		return 0;
+ 	if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) &&
+ 	    nla_len(rt) != sizeof(*rs))
+ 		return -EINVAL;
  
  	/* As only ESP and AH support ESN feature. */
  	if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))
@@@ -3258,7 -3253,6 +3253,7 @@@ static void __net_exit xfrm_user_net_ex
  static struct pernet_operations xfrm_user_net_ops = {
  	.init	    = xfrm_user_net_init,
  	.exit_batch = xfrm_user_net_exit,
 +	.async	    = true,
  };
  
  static int __init xfrm_user_init(void)

-- 
LinuxNextTracking


More information about the linux-merge mailing list