aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 90824852f59..3d7a2c0b836 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -91,9 +91,9 @@ static unsigned int udp6_portaddr_hash(struct net *net,
91 if (ipv6_addr_any(addr6)) 91 if (ipv6_addr_any(addr6))
92 hash = jhash_1word(0, mix); 92 hash = jhash_1word(0, mix);
93 else if (ipv6_addr_v4mapped(addr6)) 93 else if (ipv6_addr_v4mapped(addr6))
94 hash = jhash_1word(addr6->s6_addr32[3], mix); 94 hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
95 else 95 else
96 hash = jhash2(addr6->s6_addr32, 4, mix); 96 hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);
97 97
98 return hash ^ port; 98 return hash ^ port;
99} 99}
@@ -335,6 +335,9 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
335 if (flags & MSG_ERRQUEUE) 335 if (flags & MSG_ERRQUEUE)
336 return ipv6_recv_error(sk, msg, len); 336 return ipv6_recv_error(sk, msg, len);
337 337
338 if (np->rxpmtu && np->rxopt.bits.rxpmtu)
339 return ipv6_recv_rxpmtu(sk, msg, len);
340
338try_again: 341try_again:
339 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), 342 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
340 &peeked, &err); 343 &peeked, &err);
@@ -421,7 +424,7 @@ out:
421 return err; 424 return err;
422 425
423csum_copy_err: 426csum_copy_err:
424 lock_sock(sk); 427 lock_sock_bh(sk);
425 if (!skb_kill_datagram(sk, skb, flags)) { 428 if (!skb_kill_datagram(sk, skb, flags)) {
426 if (is_udp4) 429 if (is_udp4)
427 UDP_INC_STATS_USER(sock_net(sk), 430 UDP_INC_STATS_USER(sock_net(sk),
@@ -430,7 +433,7 @@ csum_copy_err:
430 UDP6_INC_STATS_USER(sock_net(sk), 433 UDP6_INC_STATS_USER(sock_net(sk),
431 UDP_MIB_INERRORS, is_udplite); 434 UDP_MIB_INERRORS, is_udplite);
432 } 435 }
433 release_sock(sk); 436 unlock_sock_bh(sk);
434 437
435 if (flags & MSG_DONTWAIT) 438 if (flags & MSG_DONTWAIT)
436 return -EAGAIN; 439 return -EAGAIN;
@@ -511,7 +514,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
511 goto drop; 514 goto drop;
512 } 515 }
513 516
514 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { 517 if ((rc = ip_queue_rcv_skb(sk, skb)) < 0) {
515 /* Note that an ENOMEM error is charged twice */ 518 /* Note that an ENOMEM error is charged twice */
516 if (rc == -ENOMEM) 519 if (rc == -ENOMEM)
517 UDP6_INC_STATS_BH(sock_net(sk), 520 UDP6_INC_STATS_BH(sock_net(sk),
@@ -581,6 +584,10 @@ static void flush_stack(struct sock **stack, unsigned int count,
581 584
582 sk = stack[i]; 585 sk = stack[i];
583 if (skb1) { 586 if (skb1) {
587 if (sk_rcvqueues_full(sk, skb)) {
588 kfree_skb(skb1);
589 goto drop;
590 }
584 bh_lock_sock(sk); 591 bh_lock_sock(sk);
585 if (!sock_owned_by_user(sk)) 592 if (!sock_owned_by_user(sk))
586 udpv6_queue_rcv_skb(sk, skb1); 593 udpv6_queue_rcv_skb(sk, skb1);
@@ -692,7 +699,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
692 u32 ulen = 0; 699 u32 ulen = 0;
693 700
694 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 701 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
695 goto short_packet; 702 goto discard;
696 703
697 saddr = &ipv6_hdr(skb)->saddr; 704 saddr = &ipv6_hdr(skb)->saddr;
698 daddr = &ipv6_hdr(skb)->daddr; 705 daddr = &ipv6_hdr(skb)->daddr;
@@ -756,6 +763,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
756 763
757 /* deliver */ 764 /* deliver */
758 765
766 if (sk_rcvqueues_full(sk, skb)) {
767 sock_put(sk);
768 goto discard;
769 }
759 bh_lock_sock(sk); 770 bh_lock_sock(sk);
760 if (!sock_owned_by_user(sk)) 771 if (!sock_owned_by_user(sk))
761 udpv6_queue_rcv_skb(sk, skb); 772 udpv6_queue_rcv_skb(sk, skb);
@@ -770,9 +781,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
770 return 0; 781 return 0;
771 782
772short_packet: 783short_packet:
773 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n", 784 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n",
774 proto == IPPROTO_UDPLITE ? "-Lite" : "", 785 proto == IPPROTO_UDPLITE ? "-Lite" : "",
775 ulen, skb->len); 786 saddr,
787 ntohs(uh->source),
788 ulen,
789 skb->len,
790 daddr,
791 ntohs(uh->dest));
776 792
777discard: 793discard:
778 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 794 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
@@ -919,6 +935,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
919 int ulen = len; 935 int ulen = len;
920 int hlimit = -1; 936 int hlimit = -1;
921 int tclass = -1; 937 int tclass = -1;
938 int dontfrag = -1;
922 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 939 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
923 int err; 940 int err;
924 int connected = 0; 941 int connected = 0;
@@ -1049,7 +1066,8 @@ do_udp_sendmsg:
1049 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1066 memset(opt, 0, sizeof(struct ipv6_txoptions));
1050 opt->tot_len = sizeof(*opt); 1067 opt->tot_len = sizeof(*opt);
1051 1068
1052 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); 1069 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
1070 &tclass, &dontfrag);
1053 if (err < 0) { 1071 if (err < 0) {
1054 fl6_sock_release(flowlabel); 1072 fl6_sock_release(flowlabel);
1055 return err; 1073 return err;
@@ -1120,6 +1138,9 @@ do_udp_sendmsg:
1120 if (tclass < 0) 1138 if (tclass < 0)
1121 tclass = np->tclass; 1139 tclass = np->tclass;
1122 1140
1141 if (dontfrag < 0)
1142 dontfrag = np->dontfrag;
1143
1123 if (msg->msg_flags&MSG_CONFIRM) 1144 if (msg->msg_flags&MSG_CONFIRM)
1124 goto do_confirm; 1145 goto do_confirm;
1125back_from_confirm: 1146back_from_confirm:
@@ -1143,7 +1164,7 @@ do_append_data:
1143 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, 1164 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
1144 sizeof(struct udphdr), hlimit, tclass, opt, &fl, 1165 sizeof(struct udphdr), hlimit, tclass, opt, &fl,
1145 (struct rt6_info*)dst, 1166 (struct rt6_info*)dst,
1146 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 1167 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
1147 if (err) 1168 if (err)
1148 udp_v6_flush_pending_frames(sk); 1169 udp_v6_flush_pending_frames(sk);
1149 else if (!corkreq) 1170 else if (!corkreq)