aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c123
1 files changed, 71 insertions, 52 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 63ae94771b8e..22f61aee4824 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -82,6 +82,7 @@ static void svc_delete_socket(struct svc_sock *svsk);
82static void svc_udp_data_ready(struct sock *, int); 82static void svc_udp_data_ready(struct sock *, int);
83static int svc_udp_recvfrom(struct svc_rqst *); 83static int svc_udp_recvfrom(struct svc_rqst *);
84static int svc_udp_sendto(struct svc_rqst *); 84static int svc_udp_sendto(struct svc_rqst *);
85static void svc_close_socket(struct svc_sock *svsk);
85 86
86static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk); 87static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk);
87static int svc_deferred_recv(struct svc_rqst *rqstp); 88static int svc_deferred_recv(struct svc_rqst *rqstp);
@@ -131,13 +132,13 @@ static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len)
131 NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), 132 NIPQUAD(((struct sockaddr_in *) addr)->sin_addr),
132 htons(((struct sockaddr_in *) addr)->sin_port)); 133 htons(((struct sockaddr_in *) addr)->sin_port));
133 break; 134 break;
134#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 135
135 case AF_INET6: 136 case AF_INET6:
136 snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", 137 snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u",
137 NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), 138 NIP6(((struct sockaddr_in6 *) addr)->sin6_addr),
138 htons(((struct sockaddr_in6 *) addr)->sin6_port)); 139 htons(((struct sockaddr_in6 *) addr)->sin6_port));
139 break; 140 break;
140#endif 141
141 default: 142 default:
142 snprintf(buf, len, "unknown address type: %d", addr->sa_family); 143 snprintf(buf, len, "unknown address type: %d", addr->sa_family);
143 break; 144 break;
@@ -449,10 +450,10 @@ svc_wake_up(struct svc_serv *serv)
449 450
450union svc_pktinfo_u { 451union svc_pktinfo_u {
451 struct in_pktinfo pkti; 452 struct in_pktinfo pkti;
452#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
453 struct in6_pktinfo pkti6; 453 struct in6_pktinfo pkti6;
454#endif
455}; 454};
455#define SVC_PKTINFO_SPACE \
456 CMSG_SPACE(sizeof(union svc_pktinfo_u))
456 457
457static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) 458static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
458{ 459{
@@ -467,7 +468,7 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
467 cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); 468 cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
468 } 469 }
469 break; 470 break;
470#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 471
471 case AF_INET6: { 472 case AF_INET6: {
472 struct in6_pktinfo *pki = CMSG_DATA(cmh); 473 struct in6_pktinfo *pki = CMSG_DATA(cmh);
473 474
@@ -479,7 +480,6 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
479 cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); 480 cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
480 } 481 }
481 break; 482 break;
482#endif
483 } 483 }
484 return; 484 return;
485} 485}
@@ -493,8 +493,11 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
493 struct svc_sock *svsk = rqstp->rq_sock; 493 struct svc_sock *svsk = rqstp->rq_sock;
494 struct socket *sock = svsk->sk_sock; 494 struct socket *sock = svsk->sk_sock;
495 int slen; 495 int slen;
496 char buffer[CMSG_SPACE(sizeof(union svc_pktinfo_u))]; 496 union {
497 struct cmsghdr *cmh = (struct cmsghdr *)buffer; 497 struct cmsghdr hdr;
498 long all[SVC_PKTINFO_SPACE / sizeof(long)];
499 } buffer;
500 struct cmsghdr *cmh = &buffer.hdr;
498 int len = 0; 501 int len = 0;
499 int result; 502 int result;
500 int size; 503 int size;
@@ -721,45 +724,21 @@ svc_write_space(struct sock *sk)
721 } 724 }
722} 725}
723 726
724static void svc_udp_get_sender_address(struct svc_rqst *rqstp, 727static inline void svc_udp_get_dest_address(struct svc_rqst *rqstp,
725 struct sk_buff *skb) 728 struct cmsghdr *cmh)
726{ 729{
727 switch (rqstp->rq_sock->sk_sk->sk_family) { 730 switch (rqstp->rq_sock->sk_sk->sk_family) {
728 case AF_INET: { 731 case AF_INET: {
729 /* this seems to come from net/ipv4/udp.c:udp_recvmsg */ 732 struct in_pktinfo *pki = CMSG_DATA(cmh);
730 struct sockaddr_in *sin = svc_addr_in(rqstp); 733 rqstp->rq_daddr.addr.s_addr = pki->ipi_spec_dst.s_addr;
731
732 sin->sin_family = AF_INET;
733 sin->sin_port = skb->h.uh->source;
734 sin->sin_addr.s_addr = skb->nh.iph->saddr;
735 rqstp->rq_addrlen = sizeof(struct sockaddr_in);
736 /* Remember which interface received this request */
737 rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
738 }
739 break; 734 break;
740#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
741 case AF_INET6: {
742 /* this is derived from net/ipv6/udp.c:udpv6_recvmesg */
743 struct sockaddr_in6 *sin6 = svc_addr_in6(rqstp);
744
745 sin6->sin6_family = AF_INET6;
746 sin6->sin6_port = skb->h.uh->source;
747 sin6->sin6_flowinfo = 0;
748 sin6->sin6_scope_id = 0;
749 if (ipv6_addr_type(&sin6->sin6_addr) &
750 IPV6_ADDR_LINKLOCAL)
751 sin6->sin6_scope_id = IP6CB(skb)->iif;
752 ipv6_addr_copy(&sin6->sin6_addr,
753 &skb->nh.ipv6h->saddr);
754 rqstp->rq_addrlen = sizeof(struct sockaddr_in);
755 /* Remember which interface received this request */
756 ipv6_addr_copy(&rqstp->rq_daddr.addr6,
757 &skb->nh.ipv6h->saddr);
758 } 735 }
736 case AF_INET6: {
737 struct in6_pktinfo *pki = CMSG_DATA(cmh);
738 ipv6_addr_copy(&rqstp->rq_daddr.addr6, &pki->ipi6_addr);
759 break; 739 break;
760#endif 740 }
761 } 741 }
762 return;
763} 742}
764 743
765/* 744/*
@@ -771,7 +750,18 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
771 struct svc_sock *svsk = rqstp->rq_sock; 750 struct svc_sock *svsk = rqstp->rq_sock;
772 struct svc_serv *serv = svsk->sk_server; 751 struct svc_serv *serv = svsk->sk_server;
773 struct sk_buff *skb; 752 struct sk_buff *skb;
753 union {
754 struct cmsghdr hdr;
755 long all[SVC_PKTINFO_SPACE / sizeof(long)];
756 } buffer;
757 struct cmsghdr *cmh = &buffer.hdr;
774 int err, len; 758 int err, len;
759 struct msghdr msg = {
760 .msg_name = svc_addr(rqstp),
761 .msg_control = cmh,
762 .msg_controllen = sizeof(buffer),
763 .msg_flags = MSG_DONTWAIT,
764 };
775 765
776 if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags)) 766 if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags))
777 /* udp sockets need large rcvbuf as all pending 767 /* udp sockets need large rcvbuf as all pending
@@ -797,7 +787,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
797 } 787 }
798 788
799 clear_bit(SK_DATA, &svsk->sk_flags); 789 clear_bit(SK_DATA, &svsk->sk_flags);
800 while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { 790 while ((err = kernel_recvmsg(svsk->sk_sock, &msg, NULL,
791 0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 ||
792 (skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
801 if (err == -EAGAIN) { 793 if (err == -EAGAIN) {
802 svc_sock_received(svsk); 794 svc_sock_received(svsk);
803 return err; 795 return err;
@@ -805,16 +797,13 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
805 /* possibly an icmp error */ 797 /* possibly an icmp error */
806 dprintk("svc: recvfrom returned error %d\n", -err); 798 dprintk("svc: recvfrom returned error %d\n", -err);
807 } 799 }
808 if (skb->tstamp.off_sec == 0) { 800 rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
809 struct timeval tv; 801 if (skb->tstamp.tv64 == 0) {
810 802 skb->tstamp = ktime_get_real();
811 tv.tv_sec = xtime.tv_sec;
812 tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
813 skb_set_timestamp(skb, &tv);
814 /* Don't enable netstamp, sunrpc doesn't 803 /* Don't enable netstamp, sunrpc doesn't
815 need that much accuracy */ 804 need that much accuracy */
816 } 805 }
817 skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp); 806 svsk->sk_sk->sk_stamp = skb->tstamp;
818 set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */ 807 set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
819 808
820 /* 809 /*
@@ -827,7 +816,16 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
827 816
828 rqstp->rq_prot = IPPROTO_UDP; 817 rqstp->rq_prot = IPPROTO_UDP;
829 818
830 svc_udp_get_sender_address(rqstp, skb); 819 if (cmh->cmsg_level != IPPROTO_IP ||
820 cmh->cmsg_type != IP_PKTINFO) {
821 if (net_ratelimit())
822 printk("rpcsvc: received unknown control message:"
823 "%d/%d\n",
824 cmh->cmsg_level, cmh->cmsg_type);
825 skb_free_datagram(svsk->sk_sk, skb);
826 return 0;
827 }
828 svc_udp_get_dest_address(rqstp, cmh);
831 829
832 if (skb_is_nonlinear(skb)) { 830 if (skb_is_nonlinear(skb)) {
833 /* we have to copy */ 831 /* we have to copy */
@@ -884,6 +882,9 @@ svc_udp_sendto(struct svc_rqst *rqstp)
884static void 882static void
885svc_udp_init(struct svc_sock *svsk) 883svc_udp_init(struct svc_sock *svsk)
886{ 884{
885 int one = 1;
886 mm_segment_t oldfs;
887
887 svsk->sk_sk->sk_data_ready = svc_udp_data_ready; 888 svsk->sk_sk->sk_data_ready = svc_udp_data_ready;
888 svsk->sk_sk->sk_write_space = svc_write_space; 889 svsk->sk_sk->sk_write_space = svc_write_space;
889 svsk->sk_recvfrom = svc_udp_recvfrom; 890 svsk->sk_recvfrom = svc_udp_recvfrom;
@@ -899,6 +900,13 @@ svc_udp_init(struct svc_sock *svsk)
899 900
900 set_bit(SK_DATA, &svsk->sk_flags); /* might have come in before data_ready set up */ 901 set_bit(SK_DATA, &svsk->sk_flags); /* might have come in before data_ready set up */
901 set_bit(SK_CHNGBUF, &svsk->sk_flags); 902 set_bit(SK_CHNGBUF, &svsk->sk_flags);
903
904 oldfs = get_fs();
905 set_fs(KERNEL_DS);
906 /* make sure we get destination address info */
907 svsk->sk_sock->ops->setsockopt(svsk->sk_sock, IPPROTO_IP, IP_PKTINFO,
908 (char __user *)&one, sizeof(one));
909 set_fs(oldfs);
902} 910}
903 911
904/* 912/*
@@ -977,11 +985,9 @@ static inline int svc_port_is_privileged(struct sockaddr *sin)
977 case AF_INET: 985 case AF_INET:
978 return ntohs(((struct sockaddr_in *)sin)->sin_port) 986 return ntohs(((struct sockaddr_in *)sin)->sin_port)
979 < PROT_SOCK; 987 < PROT_SOCK;
980#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
981 case AF_INET6: 988 case AF_INET6:
982 return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) 989 return ntohs(((struct sockaddr_in6 *)sin)->sin6_port)
983 < PROT_SOCK; 990 < PROT_SOCK;
984#endif
985 default: 991 default:
986 return 0; 992 return 0;
987 } 993 }
@@ -1786,7 +1792,7 @@ svc_delete_socket(struct svc_sock *svsk)
1786 spin_unlock_bh(&serv->sv_lock); 1792 spin_unlock_bh(&serv->sv_lock);
1787} 1793}
1788 1794
1789void svc_close_socket(struct svc_sock *svsk) 1795static void svc_close_socket(struct svc_sock *svsk)
1790{ 1796{
1791 set_bit(SK_CLOSE, &svsk->sk_flags); 1797 set_bit(SK_CLOSE, &svsk->sk_flags);
1792 if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) 1798 if (test_and_set_bit(SK_BUSY, &svsk->sk_flags))
@@ -1799,6 +1805,19 @@ void svc_close_socket(struct svc_sock *svsk)
1799 svc_sock_put(svsk); 1805 svc_sock_put(svsk);
1800} 1806}
1801 1807
1808void svc_force_close_socket(struct svc_sock *svsk)
1809{
1810 set_bit(SK_CLOSE, &svsk->sk_flags);
1811 if (test_bit(SK_BUSY, &svsk->sk_flags)) {
1812 /* Waiting to be processed, but no threads left,
1813 * So just remove it from the waiting list
1814 */
1815 list_del_init(&svsk->sk_ready);
1816 clear_bit(SK_BUSY, &svsk->sk_flags);
1817 }
1818 svc_close_socket(svsk);
1819}
1820
1802/** 1821/**
1803 * svc_makesock - Make a socket for nfsd and lockd 1822 * svc_makesock - Make a socket for nfsd and lockd
1804 * @serv: RPC server structure 1823 * @serv: RPC server structure