aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/af_inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r--net/ipv4/af_inet.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 33b7dffa7732..c5376c725503 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -86,6 +86,7 @@
86#include <linux/poll.h> 86#include <linux/poll.h>
87#include <linux/netfilter_ipv4.h> 87#include <linux/netfilter_ipv4.h>
88#include <linux/random.h> 88#include <linux/random.h>
89#include <linux/slab.h>
89 90
90#include <asm/uaccess.h> 91#include <asm/uaccess.h>
91#include <asm/system.h> 92#include <asm/system.h>
@@ -153,7 +154,7 @@ void inet_sock_destruct(struct sock *sk)
153 WARN_ON(sk->sk_forward_alloc); 154 WARN_ON(sk->sk_forward_alloc);
154 155
155 kfree(inet->opt); 156 kfree(inet->opt);
156 dst_release(sk->sk_dst_cache); 157 dst_release(rcu_dereference_check(sk->sk_dst_cache, 1));
157 sk_refcnt_debug_dec(sk); 158 sk_refcnt_debug_dec(sk);
158} 159}
159EXPORT_SYMBOL(inet_sock_destruct); 160EXPORT_SYMBOL(inet_sock_destruct);
@@ -418,6 +419,8 @@ int inet_release(struct socket *sock)
418 if (sk) { 419 if (sk) {
419 long timeout; 420 long timeout;
420 421
422 inet_rps_reset_flow(sk);
423
421 /* Applications forget to leave groups before exiting */ 424 /* Applications forget to leave groups before exiting */
422 ip_mc_drop_socket(sk); 425 ip_mc_drop_socket(sk);
423 426
@@ -530,6 +533,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
530{ 533{
531 struct sock *sk = sock->sk; 534 struct sock *sk = sock->sk;
532 535
536 if (addr_len < sizeof(uaddr->sa_family))
537 return -EINVAL;
533 if (uaddr->sa_family == AF_UNSPEC) 538 if (uaddr->sa_family == AF_UNSPEC)
534 return sk->sk_prot->disconnect(sk, flags); 539 return sk->sk_prot->disconnect(sk, flags);
535 540
@@ -573,6 +578,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
573 int err; 578 int err;
574 long timeo; 579 long timeo;
575 580
581 if (addr_len < sizeof(uaddr->sa_family))
582 return -EINVAL;
583
576 lock_sock(sk); 584 lock_sock(sk);
577 585
578 if (uaddr->sa_family == AF_UNSPEC) { 586 if (uaddr->sa_family == AF_UNSPEC) {
@@ -714,6 +722,8 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
714{ 722{
715 struct sock *sk = sock->sk; 723 struct sock *sk = sock->sk;
716 724
725 inet_rps_record_flow(sk);
726
717 /* We may need to bind the socket. */ 727 /* We may need to bind the socket. */
718 if (!inet_sk(sk)->inet_num && inet_autobind(sk)) 728 if (!inet_sk(sk)->inet_num && inet_autobind(sk))
719 return -EAGAIN; 729 return -EAGAIN;
@@ -722,12 +732,13 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
722} 732}
723EXPORT_SYMBOL(inet_sendmsg); 733EXPORT_SYMBOL(inet_sendmsg);
724 734
725
726static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, 735static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
727 size_t size, int flags) 736 size_t size, int flags)
728{ 737{
729 struct sock *sk = sock->sk; 738 struct sock *sk = sock->sk;
730 739
740 inet_rps_record_flow(sk);
741
731 /* We may need to bind the socket. */ 742 /* We may need to bind the socket. */
732 if (!inet_sk(sk)->inet_num && inet_autobind(sk)) 743 if (!inet_sk(sk)->inet_num && inet_autobind(sk))
733 return -EAGAIN; 744 return -EAGAIN;
@@ -737,6 +748,22 @@ static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
737 return sock_no_sendpage(sock, page, offset, size, flags); 748 return sock_no_sendpage(sock, page, offset, size, flags);
738} 749}
739 750
751int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
752 size_t size, int flags)
753{
754 struct sock *sk = sock->sk;
755 int addr_len = 0;
756 int err;
757
758 inet_rps_record_flow(sk);
759
760 err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
761 flags & ~MSG_DONTWAIT, &addr_len);
762 if (err >= 0)
763 msg->msg_namelen = addr_len;
764 return err;
765}
766EXPORT_SYMBOL(inet_recvmsg);
740 767
741int inet_shutdown(struct socket *sock, int how) 768int inet_shutdown(struct socket *sock, int how)
742{ 769{
@@ -866,7 +893,7 @@ const struct proto_ops inet_stream_ops = {
866 .setsockopt = sock_common_setsockopt, 893 .setsockopt = sock_common_setsockopt,
867 .getsockopt = sock_common_getsockopt, 894 .getsockopt = sock_common_getsockopt,
868 .sendmsg = tcp_sendmsg, 895 .sendmsg = tcp_sendmsg,
869 .recvmsg = sock_common_recvmsg, 896 .recvmsg = inet_recvmsg,
870 .mmap = sock_no_mmap, 897 .mmap = sock_no_mmap,
871 .sendpage = tcp_sendpage, 898 .sendpage = tcp_sendpage,
872 .splice_read = tcp_splice_read, 899 .splice_read = tcp_splice_read,
@@ -893,7 +920,7 @@ const struct proto_ops inet_dgram_ops = {
893 .setsockopt = sock_common_setsockopt, 920 .setsockopt = sock_common_setsockopt,
894 .getsockopt = sock_common_getsockopt, 921 .getsockopt = sock_common_getsockopt,
895 .sendmsg = inet_sendmsg, 922 .sendmsg = inet_sendmsg,
896 .recvmsg = sock_common_recvmsg, 923 .recvmsg = inet_recvmsg,
897 .mmap = sock_no_mmap, 924 .mmap = sock_no_mmap,
898 .sendpage = inet_sendpage, 925 .sendpage = inet_sendpage,
899#ifdef CONFIG_COMPAT 926#ifdef CONFIG_COMPAT
@@ -923,7 +950,7 @@ static const struct proto_ops inet_sockraw_ops = {
923 .setsockopt = sock_common_setsockopt, 950 .setsockopt = sock_common_setsockopt,
924 .getsockopt = sock_common_getsockopt, 951 .getsockopt = sock_common_getsockopt,
925 .sendmsg = inet_sendmsg, 952 .sendmsg = inet_sendmsg,
926 .recvmsg = sock_common_recvmsg, 953 .recvmsg = inet_recvmsg,
927 .mmap = sock_no_mmap, 954 .mmap = sock_no_mmap,
928 .sendpage = inet_sendpage, 955 .sendpage = inet_sendpage,
929#ifdef CONFIG_COMPAT 956#ifdef CONFIG_COMPAT
@@ -1401,10 +1428,10 @@ EXPORT_SYMBOL_GPL(snmp_fold_field);
1401int snmp_mib_init(void __percpu *ptr[2], size_t mibsize) 1428int snmp_mib_init(void __percpu *ptr[2], size_t mibsize)
1402{ 1429{
1403 BUG_ON(ptr == NULL); 1430 BUG_ON(ptr == NULL);
1404 ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); 1431 ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long));
1405 if (!ptr[0]) 1432 if (!ptr[0])
1406 goto err0; 1433 goto err0;
1407 ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); 1434 ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long));
1408 if (!ptr[1]) 1435 if (!ptr[1])
1409 goto err1; 1436 goto err1;
1410 return 0; 1437 return 0;