diff options
Diffstat (limited to 'net/ipv4/udp.c')
| -rw-r--r-- | net/ipv4/udp.c | 30 | 
1 files changed, 17 insertions, 13 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 666b963496f..4560b291180 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -307,13 +307,13 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)  static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr,  				       unsigned int port)  { -	return jhash_1word(saddr, net_hash_mix(net)) ^ port; +	return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;  }  int udp_v4_get_port(struct sock *sk, unsigned short snum)  {  	unsigned int hash2_nulladdr = -		udp4_portaddr_hash(sock_net(sk), INADDR_ANY, snum); +		udp4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum);  	unsigned int hash2_partial =  		udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); @@ -466,14 +466,14 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,  					  daddr, hnum, dif,  					  hslot2, slot2);  		if (!result) { -			hash2 = udp4_portaddr_hash(net, INADDR_ANY, hnum); +			hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum);  			slot2 = hash2 & udptable->mask;  			hslot2 = &udptable->hash2[slot2];  			if (hslot->count < hslot2->count)  				goto begin;  			result = udp4_lib_lookup2(net, saddr, sport, -						  INADDR_ANY, hnum, dif, +						  htonl(INADDR_ANY), hnum, dif,  						  hslot2, slot2);  		}  		rcu_read_unlock(); @@ -1062,10 +1062,10 @@ static unsigned int first_packet_length(struct sock *sk)  	spin_unlock_bh(&rcvq->lock);  	if (!skb_queue_empty(&list_kill)) { -		lock_sock(sk); +		lock_sock_bh(sk);  		__skb_queue_purge(&list_kill);  		sk_mem_reclaim_partial(sk); -		release_sock(sk); +		unlock_sock_bh(sk);  	}  	return res;  } @@ -1196,10 +1196,10 @@ out:  	return err;  csum_copy_err: -	lock_sock(sk); +	lock_sock_bh(sk);  	if (!skb_kill_datagram(sk, skb, flags))  		UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); -	release_sock(sk); +	unlock_sock_bh(sk);  	if (noblock)  		return -EAGAIN; @@ -1217,7 +1217,7 @@ int udp_disconnect(struct sock *sk, int flags)  	sk->sk_state = TCP_CLOSE;  	inet->inet_daddr = 0;  	inet->inet_dport = 0; -	inet_rps_save_rxhash(sk, 0); +	sock_rps_save_rxhash(sk, 0);  	sk->sk_bound_dev_if = 0;  	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))  		inet_reset_saddr(sk); @@ -1262,9 +1262,9 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)  	int rc;  	if (inet_sk(sk)->inet_daddr) -		inet_rps_save_rxhash(sk, skb->rxhash); +		sock_rps_save_rxhash(sk, skb->rxhash); -	rc = sock_queue_rcv_skb(sk, skb); +	rc = ip_queue_rcv_skb(sk, skb);  	if (rc < 0) {  		int is_udplite = IS_UDPLITE(sk); @@ -1372,6 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)  			goto drop;  	} + +	if (sk_rcvqueues_full(sk, skb)) +		goto drop; +  	rc = 0;  	bh_lock_sock(sk); @@ -1620,9 +1624,9 @@ int udp_rcv(struct sk_buff *skb)  void udp_destroy_sock(struct sock *sk)  { -	lock_sock(sk); +	lock_sock_bh(sk);  	udp_flush_pending_frames(sk); -	release_sock(sk); +	unlock_sock_bh(sk);  }  /*  |