diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/udp.c | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 7bc2d082a49e..29ebb0d27a1e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -110,11 +110,12 @@ struct udp_table udp_table; | |||
110 | EXPORT_SYMBOL(udp_table); | 110 | EXPORT_SYMBOL(udp_table); |
111 | 111 | ||
112 | int sysctl_udp_mem[3] __read_mostly; | 112 | int sysctl_udp_mem[3] __read_mostly; |
113 | int sysctl_udp_rmem_min __read_mostly; | ||
114 | int sysctl_udp_wmem_min __read_mostly; | ||
115 | |||
116 | EXPORT_SYMBOL(sysctl_udp_mem); | 113 | EXPORT_SYMBOL(sysctl_udp_mem); |
114 | |||
115 | int sysctl_udp_rmem_min __read_mostly; | ||
117 | EXPORT_SYMBOL(sysctl_udp_rmem_min); | 116 | EXPORT_SYMBOL(sysctl_udp_rmem_min); |
117 | |||
118 | int sysctl_udp_wmem_min __read_mostly; | ||
118 | EXPORT_SYMBOL(sysctl_udp_wmem_min); | 119 | EXPORT_SYMBOL(sysctl_udp_wmem_min); |
119 | 120 | ||
120 | atomic_t udp_memory_allocated; | 121 | atomic_t udp_memory_allocated; |
@@ -158,7 +159,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num, | |||
158 | */ | 159 | */ |
159 | int udp_lib_get_port(struct sock *sk, unsigned short snum, | 160 | int 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: | |||
221 | fail: | 222 | fail: |
222 | return error; | 223 | return error; |
223 | } | 224 | } |
225 | EXPORT_SYMBOL(udp_lib_get_port); | ||
224 | 226 | ||
225 | static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | 227 | static 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 | ||
234 | int udp_v4_get_port(struct sock *sk, unsigned short snum) | 236 | int udp_v4_get_port(struct sock *sk, unsigned short snum) |
@@ -383,8 +385,8 @@ found: | |||
383 | void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) | 385 | void __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 | */ |
476 | static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb, | 478 | static 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,7 +555,7 @@ 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 | ||
@@ -592,7 +594,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
592 | * Check the flags. | 594 | * Check the flags. |
593 | */ | 595 | */ |
594 | 596 | ||
595 | if (msg->msg_flags&MSG_OOB) /* Mirror BSD error message compatibility */ | 597 | if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ |
596 | return -EOPNOTSUPP; | 598 | return -EOPNOTSUPP; |
597 | 599 | ||
598 | ipc.opt = NULL; | 600 | ipc.opt = NULL; |
@@ -619,7 +621,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
619 | * Get and verify the address. | 621 | * Get and verify the address. |
620 | */ | 622 | */ |
621 | if (msg->msg_name) { | 623 | if (msg->msg_name) { |
622 | struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name; | 624 | struct sockaddr_in * usin = (struct sockaddr_in *)msg->msg_name; |
623 | if (msg->msg_namelen < sizeof(*usin)) | 625 | if (msg->msg_namelen < sizeof(*usin)) |
624 | return -EINVAL; | 626 | return -EINVAL; |
625 | if (usin->sin_family != AF_INET) { | 627 | if (usin->sin_family != AF_INET) { |
@@ -684,7 +686,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
684 | } | 686 | } |
685 | 687 | ||
686 | if (connected) | 688 | if (connected) |
687 | rt = (struct rtable*)sk_dst_check(sk, 0); | 689 | rt = (struct rtable *)sk_dst_check(sk, 0); |
688 | 690 | ||
689 | if (rt == NULL) { | 691 | if (rt == NULL) { |
690 | struct flowi fl = { .oif = ipc.oif, | 692 | struct flowi fl = { .oif = ipc.oif, |
@@ -782,6 +784,7 @@ do_confirm: | |||
782 | err = 0; | 784 | err = 0; |
783 | goto out; | 785 | goto out; |
784 | } | 786 | } |
787 | EXPORT_SYMBOL(udp_sendmsg); | ||
785 | 788 | ||
786 | int udp_sendpage(struct sock *sk, struct page *page, int offset, | 789 | int udp_sendpage(struct sock *sk, struct page *page, int offset, |
787 | size_t size, int flags) | 790 | size_t size, int flags) |
@@ -871,6 +874,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
871 | 874 | ||
872 | return 0; | 875 | return 0; |
873 | } | 876 | } |
877 | EXPORT_SYMBOL(udp_ioctl); | ||
874 | 878 | ||
875 | /* | 879 | /* |
876 | * This should be easy, if there is something there we | 880 | * This should be easy, if there is something there we |
@@ -892,7 +896,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
892 | * Check any passed addresses | 896 | * Check any passed addresses |
893 | */ | 897 | */ |
894 | if (addr_len) | 898 | if (addr_len) |
895 | *addr_len=sizeof(*sin); | 899 | *addr_len = sizeof(*sin); |
896 | 900 | ||
897 | if (flags & MSG_ERRQUEUE) | 901 | if (flags & MSG_ERRQUEUE) |
898 | return ip_recv_error(sk, msg, len); | 902 | return ip_recv_error(sk, msg, len); |
@@ -923,9 +927,11 @@ try_again: | |||
923 | 927 | ||
924 | if (skb_csum_unnecessary(skb)) | 928 | if (skb_csum_unnecessary(skb)) |
925 | err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), | 929 | err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), |
926 | msg->msg_iov, copied ); | 930 | msg->msg_iov, copied); |
927 | else { | 931 | else { |
928 | err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); | 932 | err = skb_copy_and_csum_datagram_iovec(skb, |
933 | sizeof(struct udphdr), | ||
934 | msg->msg_iov); | ||
929 | 935 | ||
930 | if (err == -EINVAL) | 936 | if (err == -EINVAL) |
931 | goto csum_copy_err; | 937 | goto csum_copy_err; |
@@ -941,8 +947,7 @@ try_again: | |||
941 | sock_recv_timestamp(msg, sk, skb); | 947 | sock_recv_timestamp(msg, sk, skb); |
942 | 948 | ||
943 | /* Copy the address. */ | 949 | /* Copy the address. */ |
944 | if (sin) | 950 | if (sin) { |
945 | { | ||
946 | sin->sin_family = AF_INET; | 951 | sin->sin_family = AF_INET; |
947 | sin->sin_port = udp_hdr(skb)->source; | 952 | sin->sin_port = udp_hdr(skb)->source; |
948 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 953 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
@@ -995,6 +1000,7 @@ int udp_disconnect(struct sock *sk, int flags) | |||
995 | sk_dst_reset(sk); | 1000 | sk_dst_reset(sk); |
996 | return 0; | 1001 | return 0; |
997 | } | 1002 | } |
1003 | EXPORT_SYMBOL(udp_disconnect); | ||
998 | 1004 | ||
999 | void udp_lib_unhash(struct sock *sk) | 1005 | void udp_lib_unhash(struct sock *sk) |
1000 | { | 1006 | { |
@@ -1044,7 +1050,7 @@ drop: | |||
1044 | * Note that in the success and error cases, the skb is assumed to | 1050 | * Note that in the success and error cases, the skb is assumed to |
1045 | * have either been requeued or freed. | 1051 | * have either been requeued or freed. |
1046 | */ | 1052 | */ |
1047 | int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | 1053 | int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1048 | { | 1054 | { |
1049 | struct udp_sock *up = udp_sk(sk); | 1055 | struct udp_sock *up = udp_sk(sk); |
1050 | int rc; | 1056 | int rc; |
@@ -1214,7 +1220,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh, | |||
1214 | if (uh->check == 0) { | 1220 | if (uh->check == 0) { |
1215 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1221 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1216 | } else if (skb->ip_summed == CHECKSUM_COMPLETE) { | 1222 | } else if (skb->ip_summed == CHECKSUM_COMPLETE) { |
1217 | if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, | 1223 | if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, |
1218 | proto, skb->csum)) | 1224 | proto, skb->csum)) |
1219 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1225 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1220 | } | 1226 | } |
@@ -1355,7 +1361,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
1355 | int err = 0; | 1361 | int err = 0; |
1356 | int is_udplite = IS_UDPLITE(sk); | 1362 | int is_udplite = IS_UDPLITE(sk); |
1357 | 1363 | ||
1358 | if (optlen<sizeof(int)) | 1364 | if (optlen < sizeof(int)) |
1359 | return -EINVAL; | 1365 | return -EINVAL; |
1360 | 1366 | ||
1361 | if (get_user(val, (int __user *)optval)) | 1367 | if (get_user(val, (int __user *)optval)) |
@@ -1426,6 +1432,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
1426 | 1432 | ||
1427 | return err; | 1433 | return err; |
1428 | } | 1434 | } |
1435 | EXPORT_SYMBOL(udp_lib_setsockopt); | ||
1429 | 1436 | ||
1430 | int udp_setsockopt(struct sock *sk, int level, int optname, | 1437 | int udp_setsockopt(struct sock *sk, int level, int optname, |
1431 | char __user *optval, int optlen) | 1438 | char __user *optval, int optlen) |
@@ -1453,7 +1460,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, | |||
1453 | struct udp_sock *up = udp_sk(sk); | 1460 | struct udp_sock *up = udp_sk(sk); |
1454 | int val, len; | 1461 | int val, len; |
1455 | 1462 | ||
1456 | if (get_user(len,optlen)) | 1463 | if (get_user(len, optlen)) |
1457 | return -EFAULT; | 1464 | return -EFAULT; |
1458 | 1465 | ||
1459 | len = min_t(unsigned int, len, sizeof(int)); | 1466 | len = min_t(unsigned int, len, sizeof(int)); |
@@ -1486,10 +1493,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, | |||
1486 | 1493 | ||
1487 | if (put_user(len, optlen)) | 1494 | if (put_user(len, optlen)) |
1488 | return -EFAULT; | 1495 | return -EFAULT; |
1489 | if (copy_to_user(optval, &val,len)) | 1496 | if (copy_to_user(optval, &val, len)) |
1490 | return -EFAULT; | 1497 | return -EFAULT; |
1491 | return 0; | 1498 | return 0; |
1492 | } | 1499 | } |
1500 | EXPORT_SYMBOL(udp_lib_getsockopt); | ||
1493 | 1501 | ||
1494 | int udp_getsockopt(struct sock *sk, int level, int optname, | 1502 | int udp_getsockopt(struct sock *sk, int level, int optname, |
1495 | char __user *optval, int __user *optlen) | 1503 | char __user *optval, int __user *optlen) |
@@ -1528,9 +1536,9 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1528 | int is_lite = IS_UDPLITE(sk); | 1536 | int is_lite = IS_UDPLITE(sk); |
1529 | 1537 | ||
1530 | /* Check for false positives due to checksum errors */ | 1538 | /* Check for false positives due to checksum errors */ |
1531 | if ( (mask & POLLRDNORM) && | 1539 | if ((mask & POLLRDNORM) && |
1532 | !(file->f_flags & O_NONBLOCK) && | 1540 | !(file->f_flags & O_NONBLOCK) && |
1533 | !(sk->sk_shutdown & RCV_SHUTDOWN)){ | 1541 | !(sk->sk_shutdown & RCV_SHUTDOWN)) { |
1534 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; | 1542 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; |
1535 | struct sk_buff *skb; | 1543 | struct sk_buff *skb; |
1536 | 1544 | ||
@@ -1552,6 +1560,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1552 | return mask; | 1560 | return mask; |
1553 | 1561 | ||
1554 | } | 1562 | } |
1563 | EXPORT_SYMBOL(udp_poll); | ||
1555 | 1564 | ||
1556 | struct proto udp_prot = { | 1565 | struct proto udp_prot = { |
1557 | .name = "UDP", | 1566 | .name = "UDP", |
@@ -1582,6 +1591,7 @@ struct proto udp_prot = { | |||
1582 | .compat_getsockopt = compat_udp_getsockopt, | 1591 | .compat_getsockopt = compat_udp_getsockopt, |
1583 | #endif | 1592 | #endif |
1584 | }; | 1593 | }; |
1594 | EXPORT_SYMBOL(udp_prot); | ||
1585 | 1595 | ||
1586 | /* ------------------------------------------------------------------------ */ | 1596 | /* ------------------------------------------------------------------------ */ |
1587 | #ifdef CONFIG_PROC_FS | 1597 | #ifdef CONFIG_PROC_FS |
@@ -1703,11 +1713,13 @@ int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo) | |||
1703 | rc = -ENOMEM; | 1713 | rc = -ENOMEM; |
1704 | return rc; | 1714 | return rc; |
1705 | } | 1715 | } |
1716 | EXPORT_SYMBOL(udp_proc_register); | ||
1706 | 1717 | ||
1707 | void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo) | 1718 | void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo) |
1708 | { | 1719 | { |
1709 | proc_net_remove(net, afinfo->name); | 1720 | proc_net_remove(net, afinfo->name); |
1710 | } | 1721 | } |
1722 | EXPORT_SYMBOL(udp_proc_unregister); | ||
1711 | 1723 | ||
1712 | /* ------------------------------------------------------------------------ */ | 1724 | /* ------------------------------------------------------------------------ */ |
1713 | static void udp4_format_sock(struct sock *sp, struct seq_file *f, | 1725 | static void udp4_format_sock(struct sock *sp, struct seq_file *f, |
@@ -1741,7 +1753,7 @@ int udp4_seq_show(struct seq_file *seq, void *v) | |||
1741 | int len; | 1753 | int len; |
1742 | 1754 | ||
1743 | udp4_format_sock(v, seq, state->bucket, &len); | 1755 | udp4_format_sock(v, seq, state->bucket, &len); |
1744 | seq_printf(seq, "%*s\n", 127 - len ,""); | 1756 | seq_printf(seq, "%*s\n", 127 - len, ""); |
1745 | } | 1757 | } |
1746 | return 0; | 1758 | return 0; |
1747 | } | 1759 | } |
@@ -1864,7 +1876,7 @@ struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features) | |||
1864 | * do checksum of UDP packets sent as multiple IP fragments. | 1876 | * do checksum of UDP packets sent as multiple IP fragments. |
1865 | */ | 1877 | */ |
1866 | offset = skb->csum_start - skb_headroom(skb); | 1878 | offset = skb->csum_start - skb_headroom(skb); |
1867 | csum = skb_checksum(skb, offset, skb->len- offset, 0); | 1879 | csum = skb_checksum(skb, offset, skb->len - offset, 0); |
1868 | offset += skb->csum_offset; | 1880 | offset += skb->csum_offset; |
1869 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); | 1881 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); |
1870 | skb->ip_summed = CHECKSUM_NONE; | 1882 | skb->ip_summed = CHECKSUM_NONE; |
@@ -1877,16 +1889,3 @@ out: | |||
1877 | return segs; | 1889 | return segs; |
1878 | } | 1890 | } |
1879 | 1891 | ||
1880 | EXPORT_SYMBOL(udp_disconnect); | ||
1881 | EXPORT_SYMBOL(udp_ioctl); | ||
1882 | EXPORT_SYMBOL(udp_prot); | ||
1883 | EXPORT_SYMBOL(udp_sendmsg); | ||
1884 | EXPORT_SYMBOL(udp_lib_getsockopt); | ||
1885 | EXPORT_SYMBOL(udp_lib_setsockopt); | ||
1886 | EXPORT_SYMBOL(udp_poll); | ||
1887 | EXPORT_SYMBOL(udp_lib_get_port); | ||
1888 | |||
1889 | #ifdef CONFIG_PROC_FS | ||
1890 | EXPORT_SYMBOL(udp_proc_register); | ||
1891 | EXPORT_SYMBOL(udp_proc_unregister); | ||
1892 | #endif | ||