diff options
Diffstat (limited to 'net/ipv4')
39 files changed, 216 insertions, 179 deletions
| diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 91a2557942fa..f48fe6fc7e8c 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -70,11 +70,9 @@ config IP_MULTIPLE_TABLES  	  address into account. Furthermore, the TOS (Type-Of-Service) field  	  of the packet can be used for routing decisions as well. -	  If you are interested in this, please see the preliminary -	  documentation at <http://www.compendium.com.ar/policy-routing.txt> -	  and <ftp://post.tepkom.ru/pub/vol2/Linux/docs/advanced-routing.tex>. -	  You will need supporting software from -	  <ftp://ftp.tux.org/pub/net/ip-routing/>. +	  If you need more information, see the Linux Advanced +	  Routing and Traffic Control documentation at +	  <http://lartc.org/howto/lartc.rpdb.html>  	  If unsure, say N. diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index afcb435adfbe..c6c8ad1d4b6d 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  #  # Makefile for the Linux TCP/IP (INET) layer.  # diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 2ae8f54cb321..82178cc69c96 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1951,7 +1951,7 @@ int cipso_v4_req_setattr(struct request_sock *req,  	buf = NULL;  	req_inet = inet_rsk(req); -	opt = xchg(&req_inet->opt, opt); +	opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt);  	if (opt)  		kfree_rcu(opt, rcu); @@ -1973,11 +1973,13 @@ req_setattr_failure:   * values on failure.   *   */ -static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr) +static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)  { +	struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1);  	int hdr_delta = 0; -	struct ip_options_rcu *opt = *opt_ptr; +	if (!opt || opt->opt.cipso == 0) +		return 0;  	if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) {  		u8 cipso_len;  		u8 cipso_off; @@ -2039,14 +2041,10 @@ static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)   */  void cipso_v4_sock_delattr(struct sock *sk)  { -	int hdr_delta; -	struct ip_options_rcu *opt;  	struct inet_sock *sk_inet; +	int hdr_delta;  	sk_inet = inet_sk(sk); -	opt = rcu_dereference_protected(sk_inet->inet_opt, 1); -	if (!opt || opt->opt.cipso == 0) -		return;  	hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt);  	if (sk_inet->is_icsk && hdr_delta > 0) { @@ -2066,15 +2064,7 @@ void cipso_v4_sock_delattr(struct sock *sk)   */  void cipso_v4_req_delattr(struct request_sock *req)  { -	struct ip_options_rcu *opt; -	struct inet_request_sock *req_inet; - -	req_inet = inet_rsk(req); -	opt = req_inet->opt; -	if (!opt || opt->opt.cipso == 0) -		return; - -	cipso_v4_delopt(&req_inet->opt); +	cipso_v4_delopt(&inet_rsk(req)->ireq_opt);  }  /** diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 5b2af19cfb5b..e6ff282bb7f4 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef _FIB_LOOKUP_H  #define _FIB_LOOKUP_H diff --git a/net/ipv4/fib_notifier.c b/net/ipv4/fib_notifier.c index cfd420b0572c..b804ccbdb241 100644 --- a/net/ipv4/fib_notifier.c +++ b/net/ipv4/fib_notifier.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <linux/rtnetlink.h>  #include <linux/notifier.h>  #include <linux/socket.h> diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 57a5d48acee8..01ed22139ac2 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -1365,8 +1365,6 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,  	    nla_put_in_addr(skb, RTA_PREFSRC, fi->fib_prefsrc))  		goto nla_put_failure;  	if (fi->fib_nhs == 1) { -		struct in_device *in_dev; -  		if (fi->fib_nh->nh_gw &&  		    nla_put_in_addr(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))  			goto nla_put_failure; @@ -1374,10 +1372,14 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,  		    nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))  			goto nla_put_failure;  		if (fi->fib_nh->nh_flags & RTNH_F_LINKDOWN) { -			in_dev = __in_dev_get_rtnl(fi->fib_nh->nh_dev); +			struct in_device *in_dev; + +			rcu_read_lock(); +			in_dev = __in_dev_get_rcu(fi->fib_nh->nh_dev);  			if (in_dev &&  			    IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))  				rtm->rtm_flags |= RTNH_F_DEAD; +			rcu_read_unlock();  		}  		if (fi->fib_nh->nh_flags & RTNH_F_OFFLOAD)  			rtm->rtm_flags |= RTNH_F_OFFLOAD; @@ -1400,18 +1402,20 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,  			goto nla_put_failure;  		for_nexthops(fi) { -			struct in_device *in_dev; -  			rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));  			if (!rtnh)  				goto nla_put_failure;  			rtnh->rtnh_flags = nh->nh_flags & 0xFF;  			if (nh->nh_flags & RTNH_F_LINKDOWN) { -				in_dev = __in_dev_get_rtnl(nh->nh_dev); +				struct in_device *in_dev; + +				rcu_read_lock(); +				in_dev = __in_dev_get_rcu(nh->nh_dev);  				if (in_dev &&  				    IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))  					rtnh->rtnh_flags |= RTNH_F_DEAD; +				rcu_read_unlock();  			}  			rtnh->rtnh_hops = nh->nh_weight - 1;  			rtnh->rtnh_ifindex = nh->nh_oif; diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index 416bb304a281..1859c473b21a 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c @@ -86,7 +86,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,  		greh = (struct gre_base_hdr *)skb_transport_header(skb);  		pcsum = (__sum16 *)(greh + 1); -		if (gso_partial) { +		if (gso_partial && skb_is_gso(skb)) {  			unsigned int partial_adj;  			/* Adjust checksum to account for the fact that diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index b9c64b40a83a..b47a59cb3573 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -266,7 +266,7 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb,  #if IS_ENABLED(CONFIG_IPV6)  	if (tb->fast_sk_family == AF_INET6)  		return ipv6_rcv_saddr_equal(&tb->fast_v6_rcv_saddr, -					    &sk->sk_v6_rcv_saddr, +					    inet6_rcv_saddr(sk),  					    tb->fast_rcv_saddr,  					    sk->sk_rcv_saddr,  					    tb->fast_ipv6_only, @@ -321,13 +321,14 @@ tb_found:  			goto fail_unlock;  	}  success: -	if (!hlist_empty(&tb->owners)) { +	if (hlist_empty(&tb->owners)) {  		tb->fastreuse = reuse;  		if (sk->sk_reuseport) {  			tb->fastreuseport = FASTREUSEPORT_ANY;  			tb->fastuid = uid;  			tb->fast_rcv_saddr = sk->sk_rcv_saddr;  			tb->fast_ipv6_only = ipv6_only_sock(sk); +			tb->fast_sk_family = sk->sk_family;  #if IS_ENABLED(CONFIG_IPV6)  			tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;  #endif @@ -354,6 +355,7 @@ success:  				tb->fastuid = uid;  				tb->fast_rcv_saddr = sk->sk_rcv_saddr;  				tb->fast_ipv6_only = ipv6_only_sock(sk); +				tb->fast_sk_family = sk->sk_family;  #if IS_ENABLED(CONFIG_IPV6)  				tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;  #endif @@ -473,6 +475,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)  		}  		spin_unlock_bh(&queue->fastopenq.lock);  	} +	mem_cgroup_sk_alloc(newsk);  out:  	release_sock(sk);  	if (req) @@ -537,9 +540,11 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,  {  	const struct inet_request_sock *ireq = inet_rsk(req);  	struct net *net = read_pnet(&ireq->ireq_net); -	struct ip_options_rcu *opt = ireq->opt; +	struct ip_options_rcu *opt;  	struct rtable *rt; +	opt = ireq_opt_deref(ireq); +  	flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,  			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,  			   sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -573,10 +578,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,  	struct flowi4 *fl4;  	struct rtable *rt; +	opt = rcu_dereference(ireq->ireq_opt);  	fl4 = &newinet->cork.fl.u.ip4; -	rcu_read_lock(); -	opt = rcu_dereference(newinet->inet_opt);  	flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,  			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,  			   sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -589,13 +593,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,  		goto no_route;  	if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)  		goto route_err; -	rcu_read_unlock();  	return &rt->dst;  route_err:  	ip_rt_put(rt);  no_route: -	rcu_read_unlock();  	__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);  	return NULL;  } diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 597bb4cfe805..e7d15fb0d94d 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -456,10 +456,7 @@ static int inet_reuseport_add_sock(struct sock *sk,  			return reuseport_add_sock(sk, sk2);  	} -	/* Initial allocation may have already happened via setsockopt */ -	if (!rcu_access_pointer(sk->sk_reuseport_cb)) -		return reuseport_alloc(sk); -	return 0; +	return reuseport_alloc(sk);  }  int __inet_hash(struct sock *sk, struct sock *osk) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e7eb590c86ce..b20c8ac64081 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -128,9 +128,9 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,  			break;  		}  		if (cmp == -1) -			pp = &(*pp)->rb_left; +			pp = &next->rb_left;  		else -			pp = &(*pp)->rb_right; +			pp = &next->rb_right;  	}  	*parent_p = parent;  	*pp_p = pp; diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 9f0a7b96646f..2dd21c3281a1 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * INET		An implementation of the TCP/IP protocol suite for the LINUX   *		operating system.  INET is implemented using the  BSD Socket diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 46408c220d9d..df8fe0503de0 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * INET		An implementation of the TCP/IP protocol suite for the LINUX   *		operating system.  INET is implemented using the  BSD Socket diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 0162fb955b33..467e44d7587d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -259,7 +259,6 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,  	struct ip_tunnel *tunnel;  	struct erspanhdr *ershdr;  	const struct iphdr *iph; -	__be32 session_id;  	__be32 index;  	int len; @@ -275,8 +274,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,  	/* The original GRE header does not have key field,  	 * Use ERSPAN 10-bit session ID as key.  	 */ -	session_id = cpu_to_be32(ntohs(ershdr->session_id)); -	tpi->key = session_id; +	tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK);  	index = ershdr->md.index;  	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,  				  tpi->flags | TUNNEL_KEY, @@ -733,7 +731,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,  	if (skb_cow_head(skb, dev->needed_headroom))  		goto free_skb; -	if (skb->len > dev->mtu) { +	if (skb->len - dev->hard_header_len > dev->mtu) {  		pskb_trim(skb, dev->mtu);  		truncate = true;  	} @@ -1223,6 +1221,7 @@ static int gre_tap_init(struct net_device *dev)  {  	__gre_tunnel_init(dev);  	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; +	netif_keep_dst(dev);  	return ip_tunnel_init(dev);  } @@ -1246,13 +1245,16 @@ static int erspan_tunnel_init(struct net_device *dev)  	tunnel->tun_hlen = 8;  	tunnel->parms.iph.protocol = IPPROTO_GRE; -	t_hlen = tunnel->hlen + sizeof(struct iphdr) + sizeof(struct erspanhdr); +	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + +		       sizeof(struct erspanhdr); +	t_hlen = tunnel->hlen + sizeof(struct iphdr);  	dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;  	dev->mtu = ETH_DATA_LEN - t_hlen - 4;  	dev->features		|= GRE_FEATURES;  	dev->hw_features	|= GRE_FEATURES;  	dev->priv_flags		|= IFF_LIVE_ADDR_CHANGE; +	netif_keep_dst(dev);  	return ip_tunnel_init(dev);  } diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index fa2dc8f692c6..57fc13c6ab2b 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -311,9 +311,10 @@ drop:  static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)  {  	const struct iphdr *iph = ip_hdr(skb); -	struct rtable *rt; +	int (*edemux)(struct sk_buff *skb);  	struct net_device *dev = skb->dev; -	void (*edemux)(struct sk_buff *skb); +	struct rtable *rt; +	int err;  	/* if ingress device is enslaved to an L3 master device pass the  	 * skb to its handler for processing @@ -331,7 +332,9 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)  		ipprot = rcu_dereference(inet_protos[protocol]);  		if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) { -			edemux(skb); +			err = edemux(skb); +			if (unlikely(err)) +				goto drop_error;  			/* must reload iph, skb->head might have changed */  			iph = ip_hdr(skb);  		} @@ -342,13 +345,10 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)  	 *	how the packet travels inside Linux networking.  	 */  	if (!skb_valid_dst(skb)) { -		int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, -					       iph->tos, dev); -		if (unlikely(err)) { -			if (err == -EXDEV) -				__NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); -			goto drop; -		} +		err = ip_route_input_noref(skb, iph->daddr, iph->saddr, +					   iph->tos, dev); +		if (unlikely(err)) +			goto drop_error;  	}  #ifdef CONFIG_IP_ROUTE_CLASSID @@ -399,6 +399,11 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)  drop:  	kfree_skb(skb);  	return NET_RX_DROP; + +drop_error: +	if (err == -EXDEV) +		__NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); +	goto drop;  }  /* diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 525ae88d1e58..ed194d46c00e 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * INET		An implementation of the TCP/IP protocol suite for the LINUX   *		operating system.  INET is implemented using the  BSD Socket diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a599aa83fdad..60fb1eb7d7d8 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * INET		An implementation of the TCP/IP protocol suite for the LINUX   *		operating system.  INET is implemented using the  BSD Socket diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 5ed63d250950..89453cf62158 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -168,6 +168,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,  	struct ip_tunnel_parm *parms = &tunnel->parms;  	struct dst_entry *dst = skb_dst(skb);  	struct net_device *tdev;	/* Device to other host */ +	int pkt_len = skb->len;  	int err;  	int mtu; @@ -229,7 +230,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,  	err = dst_output(tunnel->net, skb->sk, skb);  	if (net_xmit_eval(err) == 0) -		err = skb->len; +		err = pkt_len;  	iptunnel_xmit_stats(dev, err);  	return NETDEV_TX_OK; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 4c5dfe6bd34d..abdebca848c9 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or   *  user-supplied information to configure own IP address and routes. diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index fb1ad22b5e29..cdd627355ed1 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -128,43 +128,68 @@ static struct rtnl_link_ops ipip_link_ops __read_mostly;  static int ipip_err(struct sk_buff *skb, u32 info)  { - -/* All the routers (except for Linux) return only -   8 bytes of packet payload. It means, that precise relaying of -   ICMP in the real Internet is absolutely infeasible. - */ +	/* All the routers (except for Linux) return only +	 * 8 bytes of packet payload. It means, that precise relaying of +	 * ICMP in the real Internet is absolutely infeasible. +	 */  	struct net *net = dev_net(skb->dev);  	struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);  	const struct iphdr *iph = (const struct iphdr *)skb->data; -	struct ip_tunnel *t; -	int err;  	const int type = icmp_hdr(skb)->type;  	const int code = icmp_hdr(skb)->code; +	struct ip_tunnel *t; +	int err = 0; + +	switch (type) { +	case ICMP_DEST_UNREACH: +		switch (code) { +		case ICMP_SR_FAILED: +			/* Impossible event. */ +			goto out; +		default: +			/* All others are translated to HOST_UNREACH. +			 * rfc2003 contains "deep thoughts" about NET_UNREACH, +			 * I believe they are just ether pollution. --ANK +			 */ +			break; +		} +		break; + +	case ICMP_TIME_EXCEEDED: +		if (code != ICMP_EXC_TTL) +			goto out; +		break; + +	case ICMP_REDIRECT: +		break; + +	default: +		goto out; +	} -	err = -ENOENT;  	t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,  			     iph->daddr, iph->saddr, 0); -	if (!t) +	if (!t) { +		err = -ENOENT;  		goto out; +	}  	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { -		ipv4_update_pmtu(skb, dev_net(skb->dev), info, -				 t->parms.link, 0, iph->protocol, 0); -		err = 0; +		ipv4_update_pmtu(skb, net, info, t->parms.link, 0, +				 iph->protocol, 0);  		goto out;  	}  	if (type == ICMP_REDIRECT) { -		ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, -			      iph->protocol, 0); -		err = 0; +		ipv4_redirect(skb, net, t->parms.link, 0, iph->protocol, 0);  		goto out;  	} -	if (t->parms.iph.daddr == 0) +	if (t->parms.iph.daddr == 0) { +		err = -ENOENT;  		goto out; +	} -	err = 0;  	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)  		goto out; diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index f462fee66ac8..adcdae358365 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  #  # Makefile for the netfilter modules on top of IPv4.  # diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 811689e523c3..f75fc6b53115 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -330,7 +330,8 @@ static unsigned int ipv4_synproxy_hook(void *priv,  	if (synproxy == NULL)  		return NF_ACCEPT; -	if (nf_is_loopback_packet(skb)) +	if (nf_is_loopback_packet(skb) || +	    ip_hdr(skb)->protocol != IPPROTO_TCP)  		return NF_ACCEPT;  	thoff = ip_hdrlen(skb); diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c index eeacbdaf7cdf..5cd06ba3535d 100644 --- a/net/ipv4/netfilter/nf_reject_ipv4.c +++ b/net/ipv4/netfilter/nf_reject_ipv4.c @@ -132,6 +132,8 @@ void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook)  	if (ip_route_me_harder(net, nskb, RTN_UNSPEC))  		goto free_nskb; +	niph = ip_hdr(nskb); +  	/* "Never happens" */  	if (nskb->len > dst_mtu(skb_dst(nskb)))  		goto free_nskb; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 94d4cd2d5ea4..3d9f1c2f81c5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1520,43 +1520,56 @@ struct rtable *rt_dst_alloc(struct net_device *dev,  EXPORT_SYMBOL(rt_dst_alloc);  /* called in rcu_read_lock() section */ -static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, -				u8 tos, struct net_device *dev, int our) +int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, +			  u8 tos, struct net_device *dev, +			  struct in_device *in_dev, u32 *itag)  { -	struct rtable *rth; -	struct in_device *in_dev = __in_dev_get_rcu(dev); -	unsigned int flags = RTCF_MULTICAST; -	u32 itag = 0;  	int err;  	/* Primary sanity checks. */ -  	if (!in_dev)  		return -EINVAL;  	if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||  	    skb->protocol != htons(ETH_P_IP)) -		goto e_inval; +		return -EINVAL;  	if (ipv4_is_loopback(saddr) && !IN_DEV_ROUTE_LOCALNET(in_dev)) -		goto e_inval; +		return -EINVAL;  	if (ipv4_is_zeronet(saddr)) {  		if (!ipv4_is_local_multicast(daddr)) -			goto e_inval; +			return -EINVAL;  	} else {  		err = fib_validate_source(skb, saddr, 0, tos, 0, dev, -					  in_dev, &itag); +					  in_dev, itag);  		if (err < 0) -			goto e_err; +			return err;  	} +	return 0; +} + +/* called in rcu_read_lock() section */ +static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, +			     u8 tos, struct net_device *dev, int our) +{ +	struct in_device *in_dev = __in_dev_get_rcu(dev); +	unsigned int flags = RTCF_MULTICAST; +	struct rtable *rth; +	u32 itag = 0; +	int err; + +	err = ip_mc_validate_source(skb, daddr, saddr, tos, dev, in_dev, &itag); +	if (err) +		return err; +  	if (our)  		flags |= RTCF_LOCAL;  	rth = rt_dst_alloc(dev_net(dev)->loopback_dev, flags, RTN_MULTICAST,  			   IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false);  	if (!rth) -		goto e_nobufs; +		return -ENOBUFS;  #ifdef CONFIG_IP_ROUTE_CLASSID  	rth->dst.tclassid = itag; @@ -1572,13 +1585,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,  	skb_dst_set(skb, &rth->dst);  	return 0; - -e_nobufs: -	return -ENOBUFS; -e_inval: -	return -EINVAL; -e_err: -	return err;  } @@ -2507,7 +2513,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or  	struct rtable *ort = (struct rtable *) dst_orig;  	struct rtable *rt; -	rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, 0); +	rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_DEAD, 0);  	if (rt) {  		struct dst_entry *new = &rt->dst; diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b1bb1b3a1082..77cf32a80952 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)  	/* We throwed the options of the initial SYN away, so we hope  	 * the ACK carries the same options again (see RFC1122 4.2.3.8)  	 */ -	ireq->opt = tcp_v4_save_options(sock_net(sk), skb); +	RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb));  	if (security_inet_conn_request(sk, skb, req)) {  		reqsk_free(req); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 0d3c038d7b04..0989e739d098 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.   * diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index e3c33220c418..fbbeda647774 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <linux/crypto.h>  #include <linux/err.h>  #include <linux/init.h> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c5d7656beeee..5a87a00641d3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * INET		An implementation of the TCP/IP protocol suite for the LINUX   *		operating system.  INET is implemented using the  BSD Socket @@ -6196,7 +6197,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,  		struct inet_request_sock *ireq = inet_rsk(req);  		kmemcheck_annotate_bitfield(ireq, flags); -		ireq->opt = NULL; +		ireq->ireq_opt = NULL;  #if IS_ENABLED(CONFIG_IPV6)  		ireq->pktopts = NULL;  #endif diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d9416b5162bc..5b027c69cbc5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,  		err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,  					    ireq->ir_rmt_addr, -					    ireq->opt); +					    ireq_opt_deref(ireq));  		err = net_xmit_eval(err);  	} @@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,   */  static void tcp_v4_reqsk_destructor(struct request_sock *req)  { -	kfree(inet_rsk(req)->opt); +	kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));  }  #ifdef CONFIG_TCP_MD5SIG @@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req,  			    struct sk_buff *skb)  {  	struct inet_request_sock *ireq = inet_rsk(req); +	struct net *net = sock_net(sk_listener);  	sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);  	sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); -	ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); +	RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb));  }  static struct dst_entry *tcp_v4_route_req(const struct sock *sk, @@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,  	sk_daddr_set(newsk, ireq->ir_rmt_addr);  	sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);  	newsk->sk_bound_dev_if = ireq->ir_iif; -	newinet->inet_saddr	      = ireq->ir_loc_addr; -	inet_opt	      = ireq->opt; -	rcu_assign_pointer(newinet->inet_opt, inet_opt); -	ireq->opt	      = NULL; +	newinet->inet_saddr   = ireq->ir_loc_addr; +	inet_opt	      = rcu_dereference(ireq->ireq_opt); +	RCU_INIT_POINTER(newinet->inet_opt, inet_opt);  	newinet->mc_index     = inet_iif(skb);  	newinet->mc_ttl	      = ip_hdr(skb)->ttl;  	newinet->rcv_tos      = ip_hdr(skb)->tos; @@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,  	if (__inet_inherit_port(sk, newsk) < 0)  		goto put_and_exit;  	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); -	if (*own_req) +	if (likely(*own_req)) {  		tcp_move_syn(newtp, req); - +		ireq->ireq_opt = NULL; +	} else { +		newinet->inet_opt = NULL; +	}  	return newsk;  exit_overflow: @@ -1416,6 +1419,7 @@ exit:  	tcp_listendrop(sk);  	return NULL;  put_and_exit: +	newinet->inet_opt = NULL;  	inet_csk_prepare_forced_close(newsk);  	tcp_done(newsk);  	goto exit; @@ -1503,23 +1507,23 @@ csum_err:  }  EXPORT_SYMBOL(tcp_v4_do_rcv); -void tcp_v4_early_demux(struct sk_buff *skb) +int tcp_v4_early_demux(struct sk_buff *skb)  {  	const struct iphdr *iph;  	const struct tcphdr *th;  	struct sock *sk;  	if (skb->pkt_type != PACKET_HOST) -		return; +		return 0;  	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr))) -		return; +		return 0;  	iph = ip_hdr(skb);  	th = tcp_hdr(skb);  	if (th->doff < sizeof(struct tcphdr) / 4) -		return; +		return 0;  	sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,  				       iph->saddr, th->source, @@ -1538,6 +1542,7 @@ void tcp_v4_early_demux(struct sk_buff *skb)  				skb_dst_set_noref(skb, dst);  		}  	} +	return 0;  }  bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 102b2c90bb80..0f0d740f6c8b 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <linux/rcupdate.h>  #include <linux/spinlock.h>  #include <linux/jiffies.h> diff --git a/net/ipv4/tcp_nv.c b/net/ipv4/tcp_nv.c index 1ff73982e28c..125fc1450b01 100644 --- a/net/ipv4/tcp_nv.c +++ b/net/ipv4/tcp_nv.c @@ -252,7 +252,7 @@ static void tcpnv_acked(struct sock *sk, const struct ack_sample *sample)  	/* rate in 100's bits per second */  	rate64 = ((u64)sample->in_flight) * 8000000; -	rate = (u32)div64_u64(rate64, (u64)(avg_rtt * 100)); +	rate = (u32)div64_u64(rate64, (u64)(avg_rtt ?: 1) * 100);  	/* Remember the maximum rate seen during this RTT  	 * Note: It may be more than one RTT. This function should be diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 1c839c99114c..478909f4694d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -739,8 +739,10 @@ static void tcp_tsq_handler(struct sock *sk)  		struct tcp_sock *tp = tcp_sk(sk);  		if (tp->lost_out > tp->retrans_out && -		    tp->snd_cwnd > tcp_packets_in_flight(tp)) +		    tp->snd_cwnd > tcp_packets_in_flight(tp)) { +			tcp_mstamp_refresh(tp);  			tcp_xmit_retransmit_queue(sk); +		}  		tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle,  			       0, GFP_ATOMIC); @@ -1806,40 +1808,6 @@ static bool tcp_snd_wnd_test(const struct tcp_sock *tp,  	return !after(end_seq, tcp_wnd_end(tp));  } -/* This checks if the data bearing packet SKB (usually tcp_send_head(sk)) - * should be put on the wire right now.  If so, it returns the number of - * packets allowed by the congestion window. - */ -static unsigned int tcp_snd_test(const struct sock *sk, struct sk_buff *skb, -				 unsigned int cur_mss, int nonagle) -{ -	const struct tcp_sock *tp = tcp_sk(sk); -	unsigned int cwnd_quota; - -	tcp_init_tso_segs(skb, cur_mss); - -	if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) -		return 0; - -	cwnd_quota = tcp_cwnd_test(tp, skb); -	if (cwnd_quota && !tcp_snd_wnd_test(tp, skb, cur_mss)) -		cwnd_quota = 0; - -	return cwnd_quota; -} - -/* Test if sending is allowed right now. */ -bool tcp_may_send_now(struct sock *sk) -{ -	const struct tcp_sock *tp = tcp_sk(sk); -	struct sk_buff *skb = tcp_send_head(sk); - -	return skb && -		tcp_snd_test(sk, skb, tcp_current_mss(sk), -			     (tcp_skb_is_last(sk, skb) ? -			      tp->nonagle : TCP_NAGLE_PUSH)); -} -  /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet   * which is put after SKB on the list.  It is very much like   * tcp_fragment() except that it may make several kinds of assumptions @@ -2094,6 +2062,7 @@ static int tcp_mtu_probe(struct sock *sk)  	nskb->ip_summed = skb->ip_summed;  	tcp_insert_write_queue_before(nskb, skb, sk); +	tcp_highest_sack_replace(sk, skb, nskb);  	len = 0;  	tcp_for_write_queue_from_safe(skb, next, sk) { @@ -2271,6 +2240,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,  	sent_pkts = 0; +	tcp_mstamp_refresh(tp);  	if (!push_one) {  		/* Do MTU probing. */  		result = tcp_mtu_probe(sk); @@ -2282,7 +2252,6 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,  	}  	max_segs = tcp_tso_segs(sk, mss_now); -	tcp_mstamp_refresh(tp);  	while ((skb = tcp_send_head(sk))) {  		unsigned int limit; @@ -2697,7 +2666,7 @@ static bool tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)  		else if (!skb_shift(skb, next_skb, next_skb_size))  			return false;  	} -	tcp_highest_sack_combine(sk, next_skb, skb); +	tcp_highest_sack_replace(sk, next_skb, skb);  	tcp_unlink_write_queue(next_skb, sk); @@ -2875,8 +2844,10 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)  		nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC);  		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :  			     -ENOBUFS; -		if (!err) +		if (!err) {  			skb->skb_mstamp = tp->tcp_mstamp; +			tcp_rate_skb_sent(sk, skb); +		}  	} else {  		err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);  	} @@ -3209,13 +3180,8 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,  	th->source = htons(ireq->ir_num);  	th->dest = ireq->ir_rmt_port;  	skb->mark = ireq->ir_mark; -	/* Setting of flags are superfluous here for callers (and ECE is -	 * not even correctly set) -	 */ -	tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn, -			     TCPHDR_SYN | TCPHDR_ACK); - -	th->seq = htonl(TCP_SKB_CB(skb)->seq); +	skb->ip_summed = CHECKSUM_PARTIAL; +	th->seq = htonl(tcp_rsk(req)->snt_isn);  	/* XXX data is queued and acked as is. No buffer/window check */  	th->ack_seq = htonl(tcp_rsk(req)->rcv_nxt); @@ -3423,6 +3389,10 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)  		goto done;  	} +	/* data was not sent, this is our new send_head */ +	sk->sk_send_head = syn_data; +	tp->packets_out -= tcp_skb_pcount(syn_data); +  fallback:  	/* Send a regular SYN with Fast Open cookie request option */  	if (fo->cookie.len > 0) @@ -3475,6 +3445,11 @@ int tcp_connect(struct sock *sk)  	 */  	tp->snd_nxt = tp->write_seq;  	tp->pushed_seq = tp->write_seq; +	buff = tcp_send_head(sk); +	if (unlikely(buff)) { +		tp->snd_nxt	= TCP_SKB_CB(buff)->seq; +		tp->pushed_seq	= TCP_SKB_CB(buff)->seq; +	}  	TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS);  	/* Timer for repeating the SYN until an answer. */ diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c index 449cd914d58e..be8ef1e5dfef 100644 --- a/net/ipv4/tcp_recovery.c +++ b/net/ipv4/tcp_recovery.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <linux/tcp.h>  #include <net/tcp.h> diff --git a/net/ipv4/tcp_vegas.h b/net/ipv4/tcp_vegas.h index 248cfc0ff9ae..4f24d0e37d9c 100644 --- a/net/ipv4/tcp_vegas.h +++ b/net/ipv4/tcp_vegas.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * TCP Vegas congestion control interface   */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ef29df8648e4..ebfbccae62fd 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -231,10 +231,7 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)  		}  	} -	/* Initial allocation may have already happened via setsockopt */ -	if (!rcu_access_pointer(sk->sk_reuseport_cb)) -		return reuseport_alloc(sk); -	return 0; +	return reuseport_alloc(sk);  }  /** @@ -1061,7 +1058,7 @@ back_from_confirm:  		/* ... which is an evident application bug. --ANK */  		release_sock(sk); -		net_dbg_ratelimited("cork app bug 2\n"); +		net_dbg_ratelimited("socket already corked\n");  		err = -EINVAL;  		goto out;  	} @@ -1144,7 +1141,7 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,  	if (unlikely(!up->pending)) {  		release_sock(sk); -		net_dbg_ratelimited("udp cork app bug 3\n"); +		net_dbg_ratelimited("cork failed\n");  		return -EINVAL;  	} @@ -2221,9 +2218,10 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,  	return NULL;  } -void udp_v4_early_demux(struct sk_buff *skb) +int udp_v4_early_demux(struct sk_buff *skb)  {  	struct net *net = dev_net(skb->dev); +	struct in_device *in_dev = NULL;  	const struct iphdr *iph;  	const struct udphdr *uh;  	struct sock *sk = NULL; @@ -2234,25 +2232,21 @@ void udp_v4_early_demux(struct sk_buff *skb)  	/* validate the packet */  	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) -		return; +		return 0;  	iph = ip_hdr(skb);  	uh = udp_hdr(skb); -	if (skb->pkt_type == PACKET_BROADCAST || -	    skb->pkt_type == PACKET_MULTICAST) { -		struct in_device *in_dev = __in_dev_get_rcu(skb->dev); +	if (skb->pkt_type == PACKET_MULTICAST) { +		in_dev = __in_dev_get_rcu(skb->dev);  		if (!in_dev) -			return; +			return 0; -		/* we are supposed to accept bcast packets */ -		if (skb->pkt_type == PACKET_MULTICAST) { -			ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, -					       iph->protocol); -			if (!ours) -				return; -		} +		ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, +				       iph->protocol); +		if (!ours) +			return 0;  		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,  						   uh->source, iph->saddr, @@ -2263,7 +2257,7 @@ void udp_v4_early_demux(struct sk_buff *skb)  	}  	if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt)) -		return; +		return 0;  	skb->sk = sk;  	skb->destructor = sock_efree; @@ -2272,12 +2266,23 @@ void udp_v4_early_demux(struct sk_buff *skb)  	if (dst)  		dst = dst_check(dst, 0);  	if (dst) { +		u32 itag = 0; +  		/* set noref for now.  		 * any place which wants to hold dst has to call  		 * dst_hold_safe()  		 */  		skb_dst_set_noref(skb, dst); + +		/* for unconnected multicast sockets we need to validate +		 * the source on each packet +		 */ +		if (!inet_sk(sk)->inet_daddr && in_dev) +			return ip_mc_validate_source(skb, iph->daddr, +						     iph->saddr, iph->tos, +						     skb->dev, in_dev, &itag);  	} +	return 0;  }  int udp_rcv(struct sk_buff *skb) diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index a8cf8c6fb60c..e7d18b140287 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef _UDP4_IMPL_H  #define _UDP4_IMPL_H  #include <net/udp.h> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 97658bfc1b58..e360d55be555 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -120,7 +120,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,  		 * will be using a length value equal to only one MSS sized  		 * segment instead of the entire frame.  		 */ -		if (gso_partial) { +		if (gso_partial && skb_is_gso(skb)) {  			uh->len = htons(skb_shinfo(skb)->gso_size +  					SKB_GSO_CB(skb)->data_offset +  					skb->head - (unsigned char *)uh); diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 1fc684111ce6..e50b7fea57ee 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * xfrm4_input.c   * diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index d7bf0b041885..05017e2c849c 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * xfrm4_policy.c   * diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index d6660a8c0ea5..80c40b4981bb 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * xfrm4_state.c   * |