diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
| -rw-r--r-- | net/ipv4/af_inet.c | 43 | 
1 files changed, 17 insertions, 26 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 0189e3cd4a7d..9c465bac1eb0 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -99,6 +99,7 @@  #include <net/route.h>  #include <net/ip_fib.h>  #include <net/inet_connection_sock.h> +#include <net/gro.h>  #include <net/tcp.h>  #include <net/udp.h>  #include <net/udplite.h> @@ -154,7 +155,7 @@ void inet_sock_destruct(struct sock *sk)  	kfree(rcu_dereference_protected(inet->inet_opt, 1));  	dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1)); -	dst_release(sk->sk_rx_dst); +	dst_release(rcu_dereference_protected(sk->sk_rx_dst, 1));  	sk_refcnt_debug_dec(sk);  }  EXPORT_SYMBOL(inet_sock_destruct); @@ -224,7 +225,7 @@ int inet_listen(struct socket *sock, int backlog)  			tcp_fastopen_init_key_once(sock_net(sk));  		} -		err = inet_csk_listen_start(sk, backlog); +		err = inet_csk_listen_start(sk);  		if (err)  			goto out;  		tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_LISTEN_CB, 0, NULL); @@ -488,11 +489,8 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,  	 *  is temporarily down)  	 */  	err = -EADDRNOTAVAIL; -	if (!inet_can_nonlocal_bind(net, inet) && -	    addr->sin_addr.s_addr != htonl(INADDR_ANY) && -	    chk_addr_ret != RTN_LOCAL && -	    chk_addr_ret != RTN_MULTICAST && -	    chk_addr_ret != RTN_BROADCAST) +	if (!inet_addr_valid_or_nonlocal(net, inet, addr->sin_addr.s_addr, +	                                 chk_addr_ret))  		goto out;  	snum = ntohs(addr->sin_port); @@ -533,6 +531,8 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,  			err = BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk);  			if (err) {  				inet->inet_saddr = inet->inet_rcv_saddr = 0; +				if (sk->sk_prot->put_port) +					sk->sk_prot->put_port(sk);  				goto out_release_sock;  			}  		} @@ -1454,19 +1454,18 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)  	proto = iph->protocol; -	rcu_read_lock();  	ops = rcu_dereference(inet_offloads[proto]);  	if (!ops || !ops->callbacks.gro_receive) -		goto out_unlock; +		goto out;  	if (*(u8 *)iph != 0x45) -		goto out_unlock; +		goto out;  	if (ip_is_fragment(iph)) -		goto out_unlock; +		goto out;  	if (unlikely(ip_fast_csum((u8 *)iph, 5))) -		goto out_unlock; +		goto out;  	id = ntohl(*(__be32 *)&iph->id);  	flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF)); @@ -1543,9 +1542,6 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)  	pp = indirect_call_gro_receive(tcp4_gro_receive, udp4_gro_receive,  				       ops->callbacks.gro_receive, head, skb); -out_unlock: -	rcu_read_unlock(); -  out:  	skb_gro_flush_final(skb, pp, flush); @@ -1618,10 +1614,9 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff)  	csum_replace2(&iph->check, iph->tot_len, newlen);  	iph->tot_len = newlen; -	rcu_read_lock();  	ops = rcu_dereference(inet_offloads[proto]);  	if (WARN_ON(!ops || !ops->callbacks.gro_complete)) -		goto out_unlock; +		goto out;  	/* Only need to add sizeof(*iph) to get to the next hdr below  	 * because any hdr with option will have been flushed in @@ -1631,9 +1626,7 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff)  			      tcp4_gro_complete, udp4_gro_complete,  			      skb, nhoff + sizeof(*iph)); -out_unlock: -	rcu_read_unlock(); - +out:  	return err;  } @@ -1994,6 +1987,10 @@ static int __init inet_init(void)  	ip_init(); +	/* Initialise per-cpu ipv4 mibs */ +	if (init_ipv4_mibs()) +		panic("%s: Cannot init ipv4 mibs\n", __func__); +  	/* Setup TCP slab cache for open requests. */  	tcp_init(); @@ -2024,12 +2021,6 @@ static int __init inet_init(void)  	if (init_inet_pernet_ops())  		pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); -	/* -	 *	Initialise per-cpu ipv4 mibs -	 */ - -	if (init_ipv4_mibs()) -		pr_crit("%s: Cannot init ipv4 mibs\n", __func__);  	ipv4_proc_init();  |