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.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f0126fdd7e04..8fef859db35d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -95,6 +95,7 @@
95#include <linux/mm.h> 95#include <linux/mm.h>
96#include <linux/inet.h> 96#include <linux/inet.h>
97#include <linux/netdevice.h> 97#include <linux/netdevice.h>
98#include <linux/slab.h>
98#include <net/tcp_states.h> 99#include <net/tcp_states.h>
99#include <linux/skbuff.h> 100#include <linux/skbuff.h>
100#include <linux/proc_fs.h> 101#include <linux/proc_fs.h>
@@ -471,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
471 if (hslot->count < hslot2->count) 472 if (hslot->count < hslot2->count)
472 goto begin; 473 goto begin;
473 474
474 result = udp4_lib_lookup2(net, INADDR_ANY, sport, 475 result = udp4_lib_lookup2(net, saddr, sport,
475 daddr, hnum, dif, 476 INADDR_ANY, hnum, dif,
476 hslot2, slot2); 477 hslot2, slot2);
477 } 478 }
478 rcu_read_unlock(); 479 rcu_read_unlock();
@@ -1117,7 +1118,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1117 struct inet_sock *inet = inet_sk(sk); 1118 struct inet_sock *inet = inet_sk(sk);
1118 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; 1119 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
1119 struct sk_buff *skb; 1120 struct sk_buff *skb;
1120 unsigned int ulen, copied; 1121 unsigned int ulen;
1121 int peeked; 1122 int peeked;
1122 int err; 1123 int err;
1123 int is_udplite = IS_UDPLITE(sk); 1124 int is_udplite = IS_UDPLITE(sk);
@@ -1138,10 +1139,9 @@ try_again:
1138 goto out; 1139 goto out;
1139 1140
1140 ulen = skb->len - sizeof(struct udphdr); 1141 ulen = skb->len - sizeof(struct udphdr);
1141 copied = len; 1142 if (len > ulen)
1142 if (copied > ulen) 1143 len = ulen;
1143 copied = ulen; 1144 else if (len < ulen)
1144 else if (copied < ulen)
1145 msg->msg_flags |= MSG_TRUNC; 1145 msg->msg_flags |= MSG_TRUNC;
1146 1146
1147 /* 1147 /*
@@ -1150,14 +1150,14 @@ try_again:
1150 * coverage checksum (UDP-Lite), do it before the copy. 1150 * coverage checksum (UDP-Lite), do it before the copy.
1151 */ 1151 */
1152 1152
1153 if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) { 1153 if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
1154 if (udp_lib_checksum_complete(skb)) 1154 if (udp_lib_checksum_complete(skb))
1155 goto csum_copy_err; 1155 goto csum_copy_err;
1156 } 1156 }
1157 1157
1158 if (skb_csum_unnecessary(skb)) 1158 if (skb_csum_unnecessary(skb))
1159 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 1159 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
1160 msg->msg_iov, copied); 1160 msg->msg_iov, len);
1161 else { 1161 else {
1162 err = skb_copy_and_csum_datagram_iovec(skb, 1162 err = skb_copy_and_csum_datagram_iovec(skb,
1163 sizeof(struct udphdr), 1163 sizeof(struct udphdr),
@@ -1186,7 +1186,7 @@ try_again:
1186 if (inet->cmsg_flags) 1186 if (inet->cmsg_flags)
1187 ip_cmsg_recv(msg, skb); 1187 ip_cmsg_recv(msg, skb);
1188 1188
1189 err = copied; 1189 err = len;
1190 if (flags & MSG_TRUNC) 1190 if (flags & MSG_TRUNC)
1191 err = ulen; 1191 err = ulen;
1192 1192
@@ -1372,8 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1372 bh_lock_sock(sk); 1372 bh_lock_sock(sk);
1373 if (!sock_owned_by_user(sk)) 1373 if (!sock_owned_by_user(sk))
1374 rc = __udp_queue_rcv_skb(sk, skb); 1374 rc = __udp_queue_rcv_skb(sk, skb);
1375 else 1375 else if (sk_add_backlog(sk, skb)) {
1376 sk_add_backlog(sk, skb); 1376 bh_unlock_sock(sk);
1377 goto drop;
1378 }
1377 bh_unlock_sock(sk); 1379 bh_unlock_sock(sk);
1378 1380
1379 return rc; 1381 return rc;
@@ -2027,12 +2029,12 @@ static struct udp_seq_afinfo udp4_seq_afinfo = {
2027 }, 2029 },
2028}; 2030};
2029 2031
2030static int udp4_proc_init_net(struct net *net) 2032static int __net_init udp4_proc_init_net(struct net *net)
2031{ 2033{
2032 return udp_proc_register(net, &udp4_seq_afinfo); 2034 return udp_proc_register(net, &udp4_seq_afinfo);
2033} 2035}
2034 2036
2035static void udp4_proc_exit_net(struct net *net) 2037static void __net_exit udp4_proc_exit_net(struct net *net)
2036{ 2038{
2037 udp_proc_unregister(net, &udp4_seq_afinfo); 2039 udp_proc_unregister(net, &udp4_seq_afinfo);
2038} 2040}