aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c36522a0f113..baeec29fe0f1 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -233,7 +233,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
233 */ 233 */
234 do { 234 do {
235 if (low <= snum && snum <= high && 235 if (low <= snum && snum <= high &&
236 !test_bit(snum >> udptable->log, bitmap)) 236 !test_bit(snum >> udptable->log, bitmap) &&
237 !inet_is_reserved_local_port(snum))
237 goto found; 238 goto found;
238 snum += rand; 239 snum += rand;
239 } while (snum != first); 240 } while (snum != first);
@@ -307,13 +308,13 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
307static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr, 308static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr,
308 unsigned int port) 309 unsigned int port)
309{ 310{
310 return jhash_1word(saddr, net_hash_mix(net)) ^ port; 311 return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port;
311} 312}
312 313
313int udp_v4_get_port(struct sock *sk, unsigned short snum) 314int udp_v4_get_port(struct sock *sk, unsigned short snum)
314{ 315{
315 unsigned int hash2_nulladdr = 316 unsigned int hash2_nulladdr =
316 udp4_portaddr_hash(sock_net(sk), INADDR_ANY, snum); 317 udp4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum);
317 unsigned int hash2_partial = 318 unsigned int hash2_partial =
318 udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); 319 udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0);
319 320
@@ -466,14 +467,14 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
466 daddr, hnum, dif, 467 daddr, hnum, dif,
467 hslot2, slot2); 468 hslot2, slot2);
468 if (!result) { 469 if (!result) {
469 hash2 = udp4_portaddr_hash(net, INADDR_ANY, hnum); 470 hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
470 slot2 = hash2 & udptable->mask; 471 slot2 = hash2 & udptable->mask;
471 hslot2 = &udptable->hash2[slot2]; 472 hslot2 = &udptable->hash2[slot2];
472 if (hslot->count < hslot2->count) 473 if (hslot->count < hslot2->count)
473 goto begin; 474 goto begin;
474 475
475 result = udp4_lib_lookup2(net, saddr, sport, 476 result = udp4_lib_lookup2(net, saddr, sport,
476 INADDR_ANY, hnum, dif, 477 htonl(INADDR_ANY), hnum, dif,
477 hslot2, slot2); 478 hslot2, slot2);
478 } 479 }
479 rcu_read_unlock(); 480 rcu_read_unlock();
@@ -1062,10 +1063,10 @@ static unsigned int first_packet_length(struct sock *sk)
1062 spin_unlock_bh(&rcvq->lock); 1063 spin_unlock_bh(&rcvq->lock);
1063 1064
1064 if (!skb_queue_empty(&list_kill)) { 1065 if (!skb_queue_empty(&list_kill)) {
1065 lock_sock(sk); 1066 lock_sock_bh(sk);
1066 __skb_queue_purge(&list_kill); 1067 __skb_queue_purge(&list_kill);
1067 sk_mem_reclaim_partial(sk); 1068 sk_mem_reclaim_partial(sk);
1068 release_sock(sk); 1069 unlock_sock_bh(sk);
1069 } 1070 }
1070 return res; 1071 return res;
1071} 1072}
@@ -1196,10 +1197,10 @@ out:
1196 return err; 1197 return err;
1197 1198
1198csum_copy_err: 1199csum_copy_err:
1199 lock_sock(sk); 1200 lock_sock_bh(sk);
1200 if (!skb_kill_datagram(sk, skb, flags)) 1201 if (!skb_kill_datagram(sk, skb, flags))
1201 UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 1202 UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
1202 release_sock(sk); 1203 unlock_sock_bh(sk);
1203 1204
1204 if (noblock) 1205 if (noblock)
1205 return -EAGAIN; 1206 return -EAGAIN;
@@ -1217,6 +1218,7 @@ int udp_disconnect(struct sock *sk, int flags)
1217 sk->sk_state = TCP_CLOSE; 1218 sk->sk_state = TCP_CLOSE;
1218 inet->inet_daddr = 0; 1219 inet->inet_daddr = 0;
1219 inet->inet_dport = 0; 1220 inet->inet_dport = 0;
1221 sock_rps_save_rxhash(sk, 0);
1220 sk->sk_bound_dev_if = 0; 1222 sk->sk_bound_dev_if = 0;
1221 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) 1223 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
1222 inet_reset_saddr(sk); 1224 inet_reset_saddr(sk);
@@ -1258,8 +1260,12 @@ EXPORT_SYMBOL(udp_lib_unhash);
1258 1260
1259static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 1261static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1260{ 1262{
1261 int rc = sock_queue_rcv_skb(sk, skb); 1263 int rc;
1264
1265 if (inet_sk(sk)->inet_daddr)
1266 sock_rps_save_rxhash(sk, skb->rxhash);
1262 1267
1268 rc = ip_queue_rcv_skb(sk, skb);
1263 if (rc < 0) { 1269 if (rc < 0) {
1264 int is_udplite = IS_UDPLITE(sk); 1270 int is_udplite = IS_UDPLITE(sk);
1265 1271
@@ -1367,6 +1373,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1367 goto drop; 1373 goto drop;
1368 } 1374 }
1369 1375
1376
1377 if (sk_rcvqueues_full(sk, skb))
1378 goto drop;
1379
1370 rc = 0; 1380 rc = 0;
1371 1381
1372 bh_lock_sock(sk); 1382 bh_lock_sock(sk);
@@ -1615,9 +1625,9 @@ int udp_rcv(struct sk_buff *skb)
1615 1625
1616void udp_destroy_sock(struct sock *sk) 1626void udp_destroy_sock(struct sock *sk)
1617{ 1627{
1618 lock_sock(sk); 1628 lock_sock_bh(sk);
1619 udp_flush_pending_frames(sk); 1629 udp_flush_pending_frames(sk);
1620 release_sock(sk); 1630 unlock_sock_bh(sk);
1621} 1631}
1622 1632
1623/* 1633/*
@@ -1676,8 +1686,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1676 return -ENOPROTOOPT; 1686 return -ENOPROTOOPT;
1677 if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ 1687 if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
1678 val = 8; 1688 val = 8;
1679 else if (val > USHORT_MAX) 1689 else if (val > USHRT_MAX)
1680 val = USHORT_MAX; 1690 val = USHRT_MAX;
1681 up->pcslen = val; 1691 up->pcslen = val;
1682 up->pcflag |= UDPLITE_SEND_CC; 1692 up->pcflag |= UDPLITE_SEND_CC;
1683 break; 1693 break;
@@ -1690,8 +1700,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1690 return -ENOPROTOOPT; 1700 return -ENOPROTOOPT;
1691 if (val != 0 && val < 8) /* Avoid silly minimal values. */ 1701 if (val != 0 && val < 8) /* Avoid silly minimal values. */
1692 val = 8; 1702 val = 8;
1693 else if (val > USHORT_MAX) 1703 else if (val > USHRT_MAX)
1694 val = USHORT_MAX; 1704 val = USHRT_MAX;
1695 up->pcrlen = val; 1705 up->pcrlen = val;
1696 up->pcflag |= UDPLITE_RECV_CC; 1706 up->pcflag |= UDPLITE_RECV_CC;
1697 break; 1707 break;