diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/Kconfig | 34 | ||||
| -rw-r--r-- | net/ipv6/esp6_offload.c | 1 | ||||
| -rw-r--r-- | net/ipv6/fou6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ila/ila_main.c | 1 | ||||
| -rw-r--r-- | net/ipv6/ip6_gre.c | 20 | ||||
| -rw-r--r-- | net/ipv6/ip6_tunnel.c | 1 | ||||
| -rw-r--r-- | net/ipv6/ip6_vti.c | 1 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 15 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_SYNPROXY.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_filter.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_nat.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_raw.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_security.c | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_flow_table_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nft_dup_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nft_fib_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nft_reject_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/route.c | 7 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 1 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 17 | 
23 files changed, 117 insertions, 42 deletions
| diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 992cf45fb4f6..f4f19e89af5e 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -49,29 +49,31 @@ config IPV6_OPTIMISTIC_DAD  config INET6_AH  	tristate "IPv6: AH transformation" -	select XFRM_ALGO -	select CRYPTO -	select CRYPTO_HMAC -	select CRYPTO_MD5 -	select CRYPTO_SHA1 +	select XFRM_AH  	help -	  Support for IPsec AH. +	  Support for IPsec AH (Authentication Header). + +	  AH can be used with various authentication algorithms.  Besides +	  enabling AH support itself, this option enables the generic +	  implementations of the algorithms that RFC 8221 lists as MUST be +	  implemented.  If you need any other algorithms, you'll need to enable +	  them in the crypto API.  You should also enable accelerated +	  implementations of any needed algorithms when available.  	  If unsure, say Y.  config INET6_ESP  	tristate "IPv6: ESP transformation" -	select XFRM_ALGO -	select CRYPTO -	select CRYPTO_AUTHENC -	select CRYPTO_HMAC -	select CRYPTO_MD5 -	select CRYPTO_CBC -	select CRYPTO_SHA1 -	select CRYPTO_DES -	select CRYPTO_ECHAINIV +	select XFRM_ESP  	help -	  Support for IPsec ESP. +	  Support for IPsec ESP (Encapsulating Security Payload). + +	  ESP can be used with various encryption and authentication algorithms. +	  Besides enabling ESP support itself, this option enables the generic +	  implementations of the algorithms that RFC 8221 lists as MUST be +	  implemented.  If you need any other algorithms, you'll need to enable +	  them in the crypto API.  You should also enable accelerated +	  implementations of any needed algorithms when available.  	  If unsure, say Y. diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index 55addea1948f..1ca516fb30e1 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -395,3 +395,4 @@ module_exit(esp6_offload_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Steffen Klassert <[email protected]>");  MODULE_ALIAS_XFRM_OFFLOAD_TYPE(AF_INET6, XFRM_PROTO_ESP); +MODULE_DESCRIPTION("IPV6 GSO/GRO offload support"); diff --git a/net/ipv6/fou6.c b/net/ipv6/fou6.c index 091f94184dc1..430518ae26fa 100644 --- a/net/ipv6/fou6.c +++ b/net/ipv6/fou6.c @@ -224,3 +224,4 @@ module_init(fou6_init);  module_exit(fou6_fini);  MODULE_AUTHOR("Tom Herbert <[email protected]>");  MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Foo over UDP (IPv6)"); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fc5000370030..9df8737ae0d3 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -566,7 +566,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,  	fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);  	security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); -	sk->sk_mark = mark;  	np = inet6_sk(sk);  	if (!icmpv6_xrlim_allow(sk, type, &fl6)) @@ -583,6 +582,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,  		fl6.flowi6_oif = np->ucast_oif;  	ipcm6_init_sk(&ipc6, np); +	ipc6.sockc.mark = mark;  	fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);  	dst = icmpv6_route_lookup(net, skb, sk, &fl6); @@ -751,7 +751,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)  	sk = icmpv6_xmit_lock(net);  	if (!sk)  		goto out_bh_enable; -	sk->sk_mark = mark;  	np = inet6_sk(sk);  	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) @@ -779,6 +778,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)  	ipcm6_init_sk(&ipc6, np);  	ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);  	ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb)); +	ipc6.sockc.mark = mark;  	if (ip6_append_data(sk, icmpv6_getfrag, &msg,  			    skb->len + sizeof(struct icmp6hdr), diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c index 257d2b681246..36c58aa257e8 100644 --- a/net/ipv6/ila/ila_main.c +++ b/net/ipv6/ila/ila_main.c @@ -120,3 +120,4 @@ module_init(ila_init);  module_exit(ila_fini);  MODULE_AUTHOR("Tom Herbert <[email protected]>");  MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("IPv6: Identifier Locator Addressing (ILA)"); diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 781ca8c07a0d..3a57fb9ce049 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -127,6 +127,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,  			gre_proto == htons(ETH_P_ERSPAN2)) ?  		       ARPHRD_ETHER : ARPHRD_IP6GRE;  	int score, cand_score = 4; +	struct net_device *ndev;  	for_each_ip_tunnel_rcu(t, ign->tunnels_r_l[h0 ^ h1]) {  		if (!ipv6_addr_equal(local, &t->parms.laddr) || @@ -238,9 +239,9 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,  	if (t && t->dev->flags & IFF_UP)  		return t; -	dev = ign->fb_tunnel_dev; -	if (dev && dev->flags & IFF_UP) -		return netdev_priv(dev); +	ndev = READ_ONCE(ign->fb_tunnel_dev); +	if (ndev && ndev->flags & IFF_UP) +		return netdev_priv(ndev);  	return NULL;  } @@ -413,6 +414,8 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)  	ip6gre_tunnel_unlink_md(ign, t);  	ip6gre_tunnel_unlink(ign, t); +	if (ign->fb_tunnel_dev == dev) +		WRITE_ONCE(ign->fb_tunnel_dev, NULL);  	dst_cache_reset(&t->dst_cache);  	dev_put(dev);  } @@ -1559,17 +1562,18 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)  static int __net_init ip6gre_init_net(struct net *net)  {  	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); +	struct net_device *ndev;  	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); -	if (!ign->fb_tunnel_dev) { +	ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", +			    NET_NAME_UNKNOWN, ip6gre_tunnel_setup); +	if (!ndev) {  		err = -ENOMEM;  		goto err_alloc_dev;  	} +	ign->fb_tunnel_dev = ndev;  	dev_net_set(ign->fb_tunnel_dev, net);  	/* FB netdevice is special: we have one, and only one per netns.  	 * Allowing to move it to another netns is clearly unsafe. @@ -1589,7 +1593,7 @@ static int __net_init ip6gre_init_net(struct net *net)  	return 0;  err_reg_dev: -	free_netdev(ign->fb_tunnel_dev); +	free_netdev(ndev);  err_alloc_dev:  	return err;  } diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 821d96c720b9..a18c378ca5f4 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1846,6 +1846,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {  static void ip6_tnl_dev_setup(struct net_device *dev)  {  	dev->netdev_ops = &ip6_tnl_netdev_ops; +	dev->header_ops = &ip_tunnel_header_ops;  	dev->needs_free_netdev = true;  	dev->priv_destructor = ip6_dev_free; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 1147f647b9a0..0d964160a9dd 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -905,6 +905,7 @@ static const struct net_device_ops vti6_netdev_ops = {  static void vti6_dev_setup(struct net_device *dev)  {  	dev->netdev_ops = &vti6_netdev_ops; +	dev->header_ops = &ip_tunnel_header_ops;  	dev->needs_free_netdev = true;  	dev->priv_destructor = vti6_dev_free; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 7e12d2114158..8cd2782a31e4 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2615,6 +2615,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)  		idev->mc_list = i->next;  		write_unlock_bh(&idev->lock); +		ip6_mc_clear_src(i);  		ma_put(i);  		write_lock_bh(&idev->lock);  	} diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index e27393498ecb..e96a431549bc 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1807,11 +1807,22 @@ out_free:  	return ret;  } +void ip6t_unregister_table_pre_exit(struct net *net, struct xt_table *table, +				    const struct nf_hook_ops *ops) +{ +	nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks)); +} + +void ip6t_unregister_table_exit(struct net *net, struct xt_table *table) +{ +	__ip6t_unregister_table(net, table); +} +  void ip6t_unregister_table(struct net *net, struct xt_table *table,  			   const struct nf_hook_ops *ops)  {  	if (ops) -		nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks)); +		ip6t_unregister_table_pre_exit(net, table, ops);  	__ip6t_unregister_table(net, table);  } @@ -1969,6 +1980,8 @@ static void __exit ip6_tables_fini(void)  EXPORT_SYMBOL(ip6t_register_table);  EXPORT_SYMBOL(ip6t_unregister_table); +EXPORT_SYMBOL(ip6t_unregister_table_pre_exit); +EXPORT_SYMBOL(ip6t_unregister_table_exit);  EXPORT_SYMBOL(ip6t_do_table);  module_init(ip6_tables_init); diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index fd1f52a21bf1..d51d0c3e5fe9 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -121,3 +121,4 @@ module_exit(synproxy_tg6_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Patrick McHardy <[email protected]>"); +MODULE_DESCRIPTION("Intercept IPv6 TCP connections and establish them using syncookies"); diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 32667f5d5a33..88337b51ffbf 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c @@ -73,16 +73,24 @@ static int __net_init ip6table_filter_net_init(struct net *net)  	return 0;  } +static void __net_exit ip6table_filter_net_pre_exit(struct net *net) +{ +	if (net->ipv6.ip6table_filter) +		ip6t_unregister_table_pre_exit(net, net->ipv6.ip6table_filter, +					       filter_ops); +} +  static void __net_exit ip6table_filter_net_exit(struct net *net)  {  	if (!net->ipv6.ip6table_filter)  		return; -	ip6t_unregister_table(net, net->ipv6.ip6table_filter, filter_ops); +	ip6t_unregister_table_exit(net, net->ipv6.ip6table_filter);  	net->ipv6.ip6table_filter = NULL;  }  static struct pernet_operations ip6table_filter_net_ops = {  	.init = ip6table_filter_net_init, +	.pre_exit = ip6table_filter_net_pre_exit,  	.exit = ip6table_filter_net_exit,  }; diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 070afb97fa2b..1a2748611e00 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -93,16 +93,24 @@ static int __net_init ip6table_mangle_table_init(struct net *net)  	return ret;  } +static void __net_exit ip6table_mangle_net_pre_exit(struct net *net) +{ +	if (net->ipv6.ip6table_mangle) +		ip6t_unregister_table_pre_exit(net, net->ipv6.ip6table_mangle, +					       mangle_ops); +} +  static void __net_exit ip6table_mangle_net_exit(struct net *net)  {  	if (!net->ipv6.ip6table_mangle)  		return; -	ip6t_unregister_table(net, net->ipv6.ip6table_mangle, mangle_ops); +	ip6t_unregister_table_exit(net, net->ipv6.ip6table_mangle);  	net->ipv6.ip6table_mangle = NULL;  }  static struct pernet_operations ip6table_mangle_net_ops = { +	.pre_exit = ip6table_mangle_net_pre_exit,  	.exit = ip6table_mangle_net_exit,  }; diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index 0f4875952efc..0a23265e3caa 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c @@ -114,16 +114,22 @@ static int __net_init ip6table_nat_table_init(struct net *net)  	return ret;  } +static void __net_exit ip6table_nat_net_pre_exit(struct net *net) +{ +	if (net->ipv6.ip6table_nat) +		ip6t_nat_unregister_lookups(net); +} +  static void __net_exit ip6table_nat_net_exit(struct net *net)  {  	if (!net->ipv6.ip6table_nat)  		return; -	ip6t_nat_unregister_lookups(net); -	ip6t_unregister_table(net, net->ipv6.ip6table_nat, NULL); +	ip6t_unregister_table_exit(net, net->ipv6.ip6table_nat);  	net->ipv6.ip6table_nat = NULL;  }  static struct pernet_operations ip6table_nat_net_ops = { +	.pre_exit = ip6table_nat_net_pre_exit,  	.exit	= ip6table_nat_net_exit,  }; diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index a22100b1cf2c..8f9e742226f7 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -66,15 +66,23 @@ static int __net_init ip6table_raw_table_init(struct net *net)  	return ret;  } +static void __net_exit ip6table_raw_net_pre_exit(struct net *net) +{ +	if (net->ipv6.ip6table_raw) +		ip6t_unregister_table_pre_exit(net, net->ipv6.ip6table_raw, +					       rawtable_ops); +} +  static void __net_exit ip6table_raw_net_exit(struct net *net)  {  	if (!net->ipv6.ip6table_raw)  		return; -	ip6t_unregister_table(net, net->ipv6.ip6table_raw, rawtable_ops); +	ip6t_unregister_table_exit(net, net->ipv6.ip6table_raw);  	net->ipv6.ip6table_raw = NULL;  }  static struct pernet_operations ip6table_raw_net_ops = { +	.pre_exit = ip6table_raw_net_pre_exit,  	.exit = ip6table_raw_net_exit,  }; diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c index a74335fe2bd9..5e8c48fed032 100644 --- a/net/ipv6/netfilter/ip6table_security.c +++ b/net/ipv6/netfilter/ip6table_security.c @@ -61,15 +61,23 @@ static int __net_init ip6table_security_table_init(struct net *net)  	return ret;  } +static void __net_exit ip6table_security_net_pre_exit(struct net *net) +{ +	if (net->ipv6.ip6table_security) +		ip6t_unregister_table_pre_exit(net, net->ipv6.ip6table_security, +					       sectbl_ops); +} +  static void __net_exit ip6table_security_net_exit(struct net *net)  {  	if (!net->ipv6.ip6table_security)  		return; -	ip6t_unregister_table(net, net->ipv6.ip6table_security, sectbl_ops); +	ip6t_unregister_table_exit(net, net->ipv6.ip6table_security);  	net->ipv6.ip6table_security = NULL;  }  static struct pernet_operations ip6table_security_net_ops = { +	.pre_exit = ip6table_security_net_pre_exit,  	.exit = ip6table_security_net_exit,  }; diff --git a/net/ipv6/netfilter/nf_flow_table_ipv6.c b/net/ipv6/netfilter/nf_flow_table_ipv6.c index a8566ee12e83..667b8af2546a 100644 --- a/net/ipv6/netfilter/nf_flow_table_ipv6.c +++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c @@ -35,3 +35,4 @@ module_exit(nf_flow_ipv6_module_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");  MODULE_ALIAS_NF_FLOWTABLE(AF_INET6); +MODULE_DESCRIPTION("Netfilter flow table IPv6 module"); diff --git a/net/ipv6/netfilter/nft_dup_ipv6.c b/net/ipv6/netfilter/nft_dup_ipv6.c index 2af32200507d..8b5193efb1f1 100644 --- a/net/ipv6/netfilter/nft_dup_ipv6.c +++ b/net/ipv6/netfilter/nft_dup_ipv6.c @@ -105,3 +105,4 @@ module_exit(nft_dup_ipv6_module_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");  MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "dup"); +MODULE_DESCRIPTION("IPv6 nftables packet duplication support"); diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c index 7ece86afd079..e204163c7036 100644 --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c @@ -255,3 +255,4 @@ module_exit(nft_fib6_module_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Florian Westphal <[email protected]>");  MODULE_ALIAS_NFT_AF_EXPR(10, "fib"); +MODULE_DESCRIPTION("nftables fib / ipv6 route lookup support"); diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c index 680a28ce29fd..c1098a1968e1 100644 --- a/net/ipv6/netfilter/nft_reject_ipv6.c +++ b/net/ipv6/netfilter/nft_reject_ipv6.c @@ -72,3 +72,4 @@ module_exit(nft_reject_ipv6_module_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Patrick McHardy <[email protected]>");  MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "reject"); +MODULE_DESCRIPTION("IPv6 packet rejection for nftables"); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 82cbb46a2a4f..f3279810d765 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -431,9 +431,12 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,  	struct fib6_info *sibling, *next_sibling;  	struct fib6_info *match = res->f6i; -	if ((!match->fib6_nsiblings && !match->nh) || have_oif_match) +	if (!match->nh && (!match->fib6_nsiblings || have_oif_match))  		goto out; +	if (match->nh && have_oif_match && res->nh) +		return; +  	/* We might have already computed the hash for ICMPv6 errors. In such  	 * case it will always be non-zero. Otherwise now is the time to do it.  	 */ @@ -3402,7 +3405,7 @@ static bool fib6_is_reject(u32 flags, struct net_device *dev, int addr_type)  	if ((flags & RTF_REJECT) ||  	    (dev && (dev->flags & IFF_LOOPBACK) &&  	     !(addr_type & IPV6_ADDR_LOOPBACK) && -	     !(flags & RTF_LOCAL))) +	     !(flags & (RTF_ANYCAST | RTF_LOCAL))))  		return true;  	return false; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1fbb4dfbb191..5e2c34c0ac97 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1421,6 +1421,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)  	int t_hlen = tunnel->hlen + sizeof(struct iphdr);  	dev->netdev_ops		= &ipip6_netdev_ops; +	dev->header_ops		= &ip_tunnel_header_ops;  	dev->needs_free_netdev	= true;  	dev->priv_destructor	= ipip6_dev_free; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7d4151747340..a8d74f44056a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -148,7 +148,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,  		int dif, int sdif, struct udp_hslot *hslot2,  		struct sk_buff *skb)  { -	struct sock *sk, *result; +	struct sock *sk, *result, *reuseport_result;  	int score, badness;  	u32 hash = 0; @@ -158,17 +158,20 @@ static struct sock *udp6_lib_lookup2(struct net *net,  		score = compute_score(sk, net, saddr, sport,  				      daddr, hnum, dif, sdif);  		if (score > badness) { +			reuseport_result = NULL; +  			if (sk->sk_reuseport &&  			    sk->sk_state != TCP_ESTABLISHED) {  				hash = udp6_ehashfn(net, daddr, hnum,  						    saddr, sport); -				result = reuseport_select_sock(sk, hash, skb, -							sizeof(struct udphdr)); -				if (result && !reuseport_has_conns(sk, false)) -					return result; +				reuseport_result = reuseport_select_sock(sk, hash, skb, +									 sizeof(struct udphdr)); +				if (reuseport_result && !reuseport_has_conns(sk, false)) +					return reuseport_result;  			} -			result = sk; + +			result = reuseport_result ? : sk;  			badness = score;  		}  	} @@ -643,7 +646,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)  	/*  	 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).  	 */ -	if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) { +	if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {  		if (up->pcrlen == 0) {          /* full coverage was set  */  			net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", |