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.c156
1 files changed, 111 insertions, 45 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 80e3812837ad..ebaaa7f973d7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -110,11 +110,12 @@ struct udp_table udp_table;
110EXPORT_SYMBOL(udp_table); 110EXPORT_SYMBOL(udp_table);
111 111
112int sysctl_udp_mem[3] __read_mostly; 112int sysctl_udp_mem[3] __read_mostly;
113int sysctl_udp_rmem_min __read_mostly;
114int sysctl_udp_wmem_min __read_mostly;
115
116EXPORT_SYMBOL(sysctl_udp_mem); 113EXPORT_SYMBOL(sysctl_udp_mem);
114
115int sysctl_udp_rmem_min __read_mostly;
117EXPORT_SYMBOL(sysctl_udp_rmem_min); 116EXPORT_SYMBOL(sysctl_udp_rmem_min);
117
118int sysctl_udp_wmem_min __read_mostly;
118EXPORT_SYMBOL(sysctl_udp_wmem_min); 119EXPORT_SYMBOL(sysctl_udp_wmem_min);
119 120
120atomic_t udp_memory_allocated; 121atomic_t udp_memory_allocated;
@@ -158,7 +159,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
158 */ 159 */
159int udp_lib_get_port(struct sock *sk, unsigned short snum, 160int udp_lib_get_port(struct sock *sk, unsigned short snum,
160 int (*saddr_comp)(const struct sock *sk1, 161 int (*saddr_comp)(const struct sock *sk1,
161 const struct sock *sk2 ) ) 162 const struct sock *sk2))
162{ 163{
163 struct udp_hslot *hslot; 164 struct udp_hslot *hslot;
164 struct udp_table *udptable = sk->sk_prot->h.udp_table; 165 struct udp_table *udptable = sk->sk_prot->h.udp_table;
@@ -221,14 +222,15 @@ fail_unlock:
221fail: 222fail:
222 return error; 223 return error;
223} 224}
225EXPORT_SYMBOL(udp_lib_get_port);
224 226
225static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) 227static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
226{ 228{
227 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); 229 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
228 230
229 return ( !ipv6_only_sock(sk2) && 231 return (!ipv6_only_sock(sk2) &&
230 (!inet1->rcv_saddr || !inet2->rcv_saddr || 232 (!inet1->rcv_saddr || !inet2->rcv_saddr ||
231 inet1->rcv_saddr == inet2->rcv_saddr )); 233 inet1->rcv_saddr == inet2->rcv_saddr));
232} 234}
233 235
234int udp_v4_get_port(struct sock *sk, unsigned short snum) 236int udp_v4_get_port(struct sock *sk, unsigned short snum)
@@ -383,8 +385,8 @@ found:
383void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) 385void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
384{ 386{
385 struct inet_sock *inet; 387 struct inet_sock *inet;
386 struct iphdr *iph = (struct iphdr*)skb->data; 388 struct iphdr *iph = (struct iphdr *)skb->data;
387 struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2)); 389 struct udphdr *uh = (struct udphdr *)(skb->data+(iph->ihl<<2));
388 const int type = icmp_hdr(skb)->type; 390 const int type = icmp_hdr(skb)->type;
389 const int code = icmp_hdr(skb)->code; 391 const int code = icmp_hdr(skb)->code;
390 struct sock *sk; 392 struct sock *sk;
@@ -439,7 +441,7 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
439 if (!harderr || sk->sk_state != TCP_ESTABLISHED) 441 if (!harderr || sk->sk_state != TCP_ESTABLISHED)
440 goto out; 442 goto out;
441 } else { 443 } else {
442 ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1)); 444 ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1));
443 } 445 }
444 sk->sk_err = err; 446 sk->sk_err = err;
445 sk->sk_error_report(sk); 447 sk->sk_error_report(sk);
@@ -474,7 +476,7 @@ EXPORT_SYMBOL(udp_flush_pending_frames);
474 * (checksum field must be zeroed out) 476 * (checksum field must be zeroed out)
475 */ 477 */
476static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb, 478static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
477 __be32 src, __be32 dst, int len ) 479 __be32 src, __be32 dst, int len)
478{ 480{
479 unsigned int offset; 481 unsigned int offset;
480 struct udphdr *uh = udp_hdr(skb); 482 struct udphdr *uh = udp_hdr(skb);
@@ -545,7 +547,7 @@ static int udp_push_pending_frames(struct sock *sk)
545 547
546 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ 548 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
547 549
548 udp4_hwcsum_outgoing(sk, skb, fl->fl4_src,fl->fl4_dst, up->len); 550 udp4_hwcsum_outgoing(sk, skb, fl->fl4_src, fl->fl4_dst, up->len);
549 goto send; 551 goto send;
550 552
551 } else /* `normal' UDP */ 553 } else /* `normal' UDP */
@@ -553,18 +555,24 @@ static int udp_push_pending_frames(struct sock *sk)
553 555
554 /* add protocol-dependent pseudo-header */ 556 /* add protocol-dependent pseudo-header */
555 uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len, 557 uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len,
556 sk->sk_protocol, csum ); 558 sk->sk_protocol, csum);
557 if (uh->check == 0) 559 if (uh->check == 0)
558 uh->check = CSUM_MANGLED_0; 560 uh->check = CSUM_MANGLED_0;
559 561
560send: 562send:
561 err = ip_push_pending_frames(sk); 563 err = ip_push_pending_frames(sk);
564 if (err) {
565 if (err == -ENOBUFS && !inet->recverr) {
566 UDP_INC_STATS_USER(sock_net(sk),
567 UDP_MIB_SNDBUFERRORS, is_udplite);
568 err = 0;
569 }
570 } else
571 UDP_INC_STATS_USER(sock_net(sk),
572 UDP_MIB_OUTDATAGRAMS, is_udplite);
562out: 573out:
563 up->len = 0; 574 up->len = 0;
564 up->pending = 0; 575 up->pending = 0;
565 if (!err)
566 UDP_INC_STATS_USER(sock_net(sk),
567 UDP_MIB_OUTDATAGRAMS, is_udplite);
568 return err; 576 return err;
569} 577}
570 578
@@ -592,7 +600,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
592 * Check the flags. 600 * Check the flags.
593 */ 601 */
594 602
595 if (msg->msg_flags&MSG_OOB) /* Mirror BSD error message compatibility */ 603 if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
596 return -EOPNOTSUPP; 604 return -EOPNOTSUPP;
597 605
598 ipc.opt = NULL; 606 ipc.opt = NULL;
@@ -619,7 +627,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
619 * Get and verify the address. 627 * Get and verify the address.
620 */ 628 */
621 if (msg->msg_name) { 629 if (msg->msg_name) {
622 struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name; 630 struct sockaddr_in * usin = (struct sockaddr_in *)msg->msg_name;
623 if (msg->msg_namelen < sizeof(*usin)) 631 if (msg->msg_namelen < sizeof(*usin))
624 return -EINVAL; 632 return -EINVAL;
625 if (usin->sin_family != AF_INET) { 633 if (usin->sin_family != AF_INET) {
@@ -684,7 +692,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
684 } 692 }
685 693
686 if (connected) 694 if (connected)
687 rt = (struct rtable*)sk_dst_check(sk, 0); 695 rt = (struct rtable *)sk_dst_check(sk, 0);
688 696
689 if (rt == NULL) { 697 if (rt == NULL) {
690 struct flowi fl = { .oif = ipc.oif, 698 struct flowi fl = { .oif = ipc.oif,
@@ -782,6 +790,7 @@ do_confirm:
782 err = 0; 790 err = 0;
783 goto out; 791 goto out;
784} 792}
793EXPORT_SYMBOL(udp_sendmsg);
785 794
786int udp_sendpage(struct sock *sk, struct page *page, int offset, 795int udp_sendpage(struct sock *sk, struct page *page, int offset,
787 size_t size, int flags) 796 size_t size, int flags)
@@ -871,6 +880,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
871 880
872 return 0; 881 return 0;
873} 882}
883EXPORT_SYMBOL(udp_ioctl);
874 884
875/* 885/*
876 * This should be easy, if there is something there we 886 * This should be easy, if there is something there we
@@ -892,7 +902,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
892 * Check any passed addresses 902 * Check any passed addresses
893 */ 903 */
894 if (addr_len) 904 if (addr_len)
895 *addr_len=sizeof(*sin); 905 *addr_len = sizeof(*sin);
896 906
897 if (flags & MSG_ERRQUEUE) 907 if (flags & MSG_ERRQUEUE)
898 return ip_recv_error(sk, msg, len); 908 return ip_recv_error(sk, msg, len);
@@ -923,9 +933,11 @@ try_again:
923 933
924 if (skb_csum_unnecessary(skb)) 934 if (skb_csum_unnecessary(skb))
925 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 935 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
926 msg->msg_iov, copied ); 936 msg->msg_iov, copied);
927 else { 937 else {
928 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 938 err = skb_copy_and_csum_datagram_iovec(skb,
939 sizeof(struct udphdr),
940 msg->msg_iov);
929 941
930 if (err == -EINVAL) 942 if (err == -EINVAL)
931 goto csum_copy_err; 943 goto csum_copy_err;
@@ -941,8 +953,7 @@ try_again:
941 sock_recv_timestamp(msg, sk, skb); 953 sock_recv_timestamp(msg, sk, skb);
942 954
943 /* Copy the address. */ 955 /* Copy the address. */
944 if (sin) 956 if (sin) {
945 {
946 sin->sin_family = AF_INET; 957 sin->sin_family = AF_INET;
947 sin->sin_port = udp_hdr(skb)->source; 958 sin->sin_port = udp_hdr(skb)->source;
948 sin->sin_addr.s_addr = ip_hdr(skb)->saddr; 959 sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
@@ -995,6 +1006,7 @@ int udp_disconnect(struct sock *sk, int flags)
995 sk_dst_reset(sk); 1006 sk_dst_reset(sk);
996 return 0; 1007 return 0;
997} 1008}
1009EXPORT_SYMBOL(udp_disconnect);
998 1010
999void udp_lib_unhash(struct sock *sk) 1011void udp_lib_unhash(struct sock *sk)
1000{ 1012{
@@ -1044,7 +1056,7 @@ drop:
1044 * Note that in the success and error cases, the skb is assumed to 1056 * Note that in the success and error cases, the skb is assumed to
1045 * have either been requeued or freed. 1057 * have either been requeued or freed.
1046 */ 1058 */
1047int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 1059int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1048{ 1060{
1049 struct udp_sock *up = udp_sk(sk); 1061 struct udp_sock *up = udp_sk(sk);
1050 int rc; 1062 int rc;
@@ -1214,7 +1226,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
1214 if (uh->check == 0) { 1226 if (uh->check == 0) {
1215 skb->ip_summed = CHECKSUM_UNNECESSARY; 1227 skb->ip_summed = CHECKSUM_UNNECESSARY;
1216 } else if (skb->ip_summed == CHECKSUM_COMPLETE) { 1228 } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
1217 if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, 1229 if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
1218 proto, skb->csum)) 1230 proto, skb->csum))
1219 skb->ip_summed = CHECKSUM_UNNECESSARY; 1231 skb->ip_summed = CHECKSUM_UNNECESSARY;
1220 } 1232 }
@@ -1355,7 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1355 int err = 0; 1367 int err = 0;
1356 int is_udplite = IS_UDPLITE(sk); 1368 int is_udplite = IS_UDPLITE(sk);
1357 1369
1358 if (optlen<sizeof(int)) 1370 if (optlen < sizeof(int))
1359 return -EINVAL; 1371 return -EINVAL;
1360 1372
1361 if (get_user(val, (int __user *)optval)) 1373 if (get_user(val, (int __user *)optval))
@@ -1426,6 +1438,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1426 1438
1427 return err; 1439 return err;
1428} 1440}
1441EXPORT_SYMBOL(udp_lib_setsockopt);
1429 1442
1430int udp_setsockopt(struct sock *sk, int level, int optname, 1443int udp_setsockopt(struct sock *sk, int level, int optname,
1431 char __user *optval, int optlen) 1444 char __user *optval, int optlen)
@@ -1453,7 +1466,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
1453 struct udp_sock *up = udp_sk(sk); 1466 struct udp_sock *up = udp_sk(sk);
1454 int val, len; 1467 int val, len;
1455 1468
1456 if (get_user(len,optlen)) 1469 if (get_user(len, optlen))
1457 return -EFAULT; 1470 return -EFAULT;
1458 1471
1459 len = min_t(unsigned int, len, sizeof(int)); 1472 len = min_t(unsigned int, len, sizeof(int));
@@ -1486,10 +1499,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
1486 1499
1487 if (put_user(len, optlen)) 1500 if (put_user(len, optlen))
1488 return -EFAULT; 1501 return -EFAULT;
1489 if (copy_to_user(optval, &val,len)) 1502 if (copy_to_user(optval, &val, len))
1490 return -EFAULT; 1503 return -EFAULT;
1491 return 0; 1504 return 0;
1492} 1505}
1506EXPORT_SYMBOL(udp_lib_getsockopt);
1493 1507
1494int udp_getsockopt(struct sock *sk, int level, int optname, 1508int udp_getsockopt(struct sock *sk, int level, int optname,
1495 char __user *optval, int __user *optlen) 1509 char __user *optval, int __user *optlen)
@@ -1528,9 +1542,9 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1528 int is_lite = IS_UDPLITE(sk); 1542 int is_lite = IS_UDPLITE(sk);
1529 1543
1530 /* Check for false positives due to checksum errors */ 1544 /* Check for false positives due to checksum errors */
1531 if ( (mask & POLLRDNORM) && 1545 if ((mask & POLLRDNORM) &&
1532 !(file->f_flags & O_NONBLOCK) && 1546 !(file->f_flags & O_NONBLOCK) &&
1533 !(sk->sk_shutdown & RCV_SHUTDOWN)){ 1547 !(sk->sk_shutdown & RCV_SHUTDOWN)) {
1534 struct sk_buff_head *rcvq = &sk->sk_receive_queue; 1548 struct sk_buff_head *rcvq = &sk->sk_receive_queue;
1535 struct sk_buff *skb; 1549 struct sk_buff *skb;
1536 1550
@@ -1552,6 +1566,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1552 return mask; 1566 return mask;
1553 1567
1554} 1568}
1569EXPORT_SYMBOL(udp_poll);
1555 1570
1556struct proto udp_prot = { 1571struct proto udp_prot = {
1557 .name = "UDP", 1572 .name = "UDP",
@@ -1582,6 +1597,7 @@ struct proto udp_prot = {
1582 .compat_getsockopt = compat_udp_getsockopt, 1597 .compat_getsockopt = compat_udp_getsockopt,
1583#endif 1598#endif
1584}; 1599};
1600EXPORT_SYMBOL(udp_prot);
1585 1601
1586/* ------------------------------------------------------------------------ */ 1602/* ------------------------------------------------------------------------ */
1587#ifdef CONFIG_PROC_FS 1603#ifdef CONFIG_PROC_FS
@@ -1703,11 +1719,13 @@ int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo)
1703 rc = -ENOMEM; 1719 rc = -ENOMEM;
1704 return rc; 1720 return rc;
1705} 1721}
1722EXPORT_SYMBOL(udp_proc_register);
1706 1723
1707void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo) 1724void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
1708{ 1725{
1709 proc_net_remove(net, afinfo->name); 1726 proc_net_remove(net, afinfo->name);
1710} 1727}
1728EXPORT_SYMBOL(udp_proc_unregister);
1711 1729
1712/* ------------------------------------------------------------------------ */ 1730/* ------------------------------------------------------------------------ */
1713static void udp4_format_sock(struct sock *sp, struct seq_file *f, 1731static void udp4_format_sock(struct sock *sp, struct seq_file *f,
@@ -1741,7 +1759,7 @@ int udp4_seq_show(struct seq_file *seq, void *v)
1741 int len; 1759 int len;
1742 1760
1743 udp4_format_sock(v, seq, state->bucket, &len); 1761 udp4_format_sock(v, seq, state->bucket, &len);
1744 seq_printf(seq, "%*s\n", 127 - len ,""); 1762 seq_printf(seq, "%*s\n", 127 - len, "");
1745 } 1763 }
1746 return 0; 1764 return 0;
1747} 1765}
@@ -1816,16 +1834,64 @@ void __init udp_init(void)
1816 sysctl_udp_wmem_min = SK_MEM_QUANTUM; 1834 sysctl_udp_wmem_min = SK_MEM_QUANTUM;
1817} 1835}
1818 1836
1819EXPORT_SYMBOL(udp_disconnect); 1837int udp4_ufo_send_check(struct sk_buff *skb)
1820EXPORT_SYMBOL(udp_ioctl); 1838{
1821EXPORT_SYMBOL(udp_prot); 1839 const struct iphdr *iph;
1822EXPORT_SYMBOL(udp_sendmsg); 1840 struct udphdr *uh;
1823EXPORT_SYMBOL(udp_lib_getsockopt); 1841
1824EXPORT_SYMBOL(udp_lib_setsockopt); 1842 if (!pskb_may_pull(skb, sizeof(*uh)))
1825EXPORT_SYMBOL(udp_poll); 1843 return -EINVAL;
1826EXPORT_SYMBOL(udp_lib_get_port); 1844
1845 iph = ip_hdr(skb);
1846 uh = udp_hdr(skb);
1847
1848 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
1849 IPPROTO_UDP, 0);
1850 skb->csum_start = skb_transport_header(skb) - skb->head;
1851 skb->csum_offset = offsetof(struct udphdr, check);
1852 skb->ip_summed = CHECKSUM_PARTIAL;
1853 return 0;
1854}
1855
1856struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features)
1857{
1858 struct sk_buff *segs = ERR_PTR(-EINVAL);
1859 unsigned int mss;
1860 int offset;
1861 __wsum csum;
1862
1863 mss = skb_shinfo(skb)->gso_size;
1864 if (unlikely(skb->len <= mss))
1865 goto out;
1866
1867 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
1868 /* Packet is from an untrusted source, reset gso_segs. */
1869 int type = skb_shinfo(skb)->gso_type;
1870
1871 if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY) ||
1872 !(type & (SKB_GSO_UDP))))
1873 goto out;
1874
1875 skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
1876
1877 segs = NULL;
1878 goto out;
1879 }
1880
1881 /* Do software UFO. Complete and fill in the UDP checksum as HW cannot
1882 * do checksum of UDP packets sent as multiple IP fragments.
1883 */
1884 offset = skb->csum_start - skb_headroom(skb);
1885 csum = skb_checksum(skb, offset, skb->len - offset, 0);
1886 offset += skb->csum_offset;
1887 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
1888 skb->ip_summed = CHECKSUM_NONE;
1889
1890 /* Fragment the skb. IP headers of the fragments are updated in
1891 * inet_gso_segment()
1892 */
1893 segs = skb_segment(skb, features);
1894out:
1895 return segs;
1896}
1827 1897
1828#ifdef CONFIG_PROC_FS
1829EXPORT_SYMBOL(udp_proc_register);
1830EXPORT_SYMBOL(udp_proc_unregister);
1831#endif