diff options
| -rw-r--r-- | net/sunrpc/svc.c | 143 |
1 files changed, 100 insertions, 43 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index c43ccb628052..b8d2fcd0f715 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -720,69 +720,125 @@ svc_exit_thread(struct svc_rqst *rqstp) | |||
| 720 | EXPORT_SYMBOL(svc_exit_thread); | 720 | EXPORT_SYMBOL(svc_exit_thread); |
| 721 | 721 | ||
| 722 | #ifdef CONFIG_SUNRPC_REGISTER_V4 | 722 | #ifdef CONFIG_SUNRPC_REGISTER_V4 |
| 723 | |||
| 723 | /* | 724 | /* |
| 724 | * Registering kernel RPC services with rpcbind version 2 will work | 725 | * Register an "inet" protocol family netid with the local |
| 725 | * over either IPv4 or IPv6, since the Linux kernel always registers | 726 | * rpcbind daemon via an rpcbind v4 SET request. |
| 726 | * services for the "any" address. | ||
| 727 | * | ||
| 728 | * However, the local rpcbind daemon listens on either only AF_INET | ||
| 729 | * or AF_INET6 (never both). When it listens on AF_INET6, an rpcbind | ||
| 730 | * version 2 registration will result in registering the service at | ||
| 731 | * IN6ADDR_ANY, even if the RPC service being registered is not | ||
| 732 | * IPv6-enabled. | ||
| 733 | * | 727 | * |
| 734 | * Rpcbind version 4 allows us to be a little more specific. Kernel | 728 | * No netconfig infrastructure is available in the kernel, so |
| 735 | * RPC services that don't yet support AF_INET6 can register | 729 | * we map IP_ protocol numbers to netids by hand. |
| 736 | * themselves as IPv4-only with the local rpcbind daemon, even if the | ||
| 737 | * daemon is listening only on AF_INET6. | ||
| 738 | * | 730 | * |
| 739 | * And, registering IPv6-enabled kernel RPC services via AF_INET6 | 731 | * Returns zero on success; a negative errno value is returned |
| 740 | * verifies that the local user space rpcbind daemon is properly | 732 | * if any error occurs. |
| 741 | * configured to support remote AF_INET6 rpcbind requests. | ||
| 742 | * | ||
| 743 | * An AF_INET6 registration request will fail if the local rpcbind | ||
| 744 | * daemon is not set up to listen on AF_INET6. Likewise, we fail | ||
| 745 | * AF_INET6 registration requests if svc_register() is configured to | ||
| 746 | * support only rpcbind version 2. | ||
| 747 | */ | 733 | */ |
| 748 | static int __svc_register(const u32 program, const u32 version, | 734 | static int __svc_rpcb_register4(const u32 program, const u32 version, |
| 749 | const sa_family_t family, | 735 | const unsigned short protocol, |
| 750 | const unsigned short protocol, | 736 | const unsigned short port) |
| 751 | const unsigned short port) | ||
| 752 | { | 737 | { |
| 753 | struct sockaddr_in sin = { | 738 | struct sockaddr_in sin = { |
| 754 | .sin_family = AF_INET, | 739 | .sin_family = AF_INET, |
| 755 | .sin_addr.s_addr = htonl(INADDR_ANY), | 740 | .sin_addr.s_addr = htonl(INADDR_ANY), |
| 756 | .sin_port = htons(port), | 741 | .sin_port = htons(port), |
| 757 | }; | 742 | }; |
| 743 | char *netid; | ||
| 744 | |||
| 745 | switch (protocol) { | ||
| 746 | case IPPROTO_UDP: | ||
| 747 | netid = RPCBIND_NETID_UDP; | ||
| 748 | break; | ||
| 749 | case IPPROTO_TCP: | ||
| 750 | netid = RPCBIND_NETID_TCP; | ||
| 751 | break; | ||
| 752 | default: | ||
| 753 | return -EPROTONOSUPPORT; | ||
| 754 | } | ||
| 755 | |||
| 756 | return rpcb_v4_register(program, version, | ||
| 757 | (struct sockaddr *)&sin, netid); | ||
| 758 | } | ||
| 759 | |||
| 760 | /* | ||
| 761 | * Register an "inet6" protocol family netid with the local | ||
| 762 | * rpcbind daemon via an rpcbind v4 SET request. | ||
| 763 | * | ||
| 764 | * No netconfig infrastructure is available in the kernel, so | ||
| 765 | * we map IP_ protocol numbers to netids by hand. | ||
| 766 | * | ||
| 767 | * Returns zero on success; a negative errno value is returned | ||
| 768 | * if any error occurs. | ||
| 769 | */ | ||
| 770 | static int __svc_rpcb_register6(const u32 program, const u32 version, | ||
| 771 | const unsigned short protocol, | ||
| 772 | const unsigned short port) | ||
| 773 | { | ||
| 758 | struct sockaddr_in6 sin6 = { | 774 | struct sockaddr_in6 sin6 = { |
| 759 | .sin6_family = AF_INET6, | 775 | .sin6_family = AF_INET6, |
| 760 | .sin6_addr = IN6ADDR_ANY_INIT, | 776 | .sin6_addr = IN6ADDR_ANY_INIT, |
| 761 | .sin6_port = htons(port), | 777 | .sin6_port = htons(port), |
| 762 | }; | 778 | }; |
| 763 | struct sockaddr *sap; | ||
| 764 | char *netid; | 779 | char *netid; |
| 765 | 780 | ||
| 766 | switch (family) { | 781 | switch (protocol) { |
| 767 | case AF_INET: | 782 | case IPPROTO_UDP: |
| 768 | sap = (struct sockaddr *)&sin; | 783 | netid = RPCBIND_NETID_UDP6; |
| 769 | netid = RPCBIND_NETID_TCP; | ||
| 770 | if (protocol == IPPROTO_UDP) | ||
| 771 | netid = RPCBIND_NETID_UDP; | ||
| 772 | break; | 784 | break; |
| 773 | case AF_INET6: | 785 | case IPPROTO_TCP: |
| 774 | sap = (struct sockaddr *)&sin6; | ||
| 775 | netid = RPCBIND_NETID_TCP6; | 786 | netid = RPCBIND_NETID_TCP6; |
| 776 | if (protocol == IPPROTO_UDP) | ||
| 777 | netid = RPCBIND_NETID_UDP6; | ||
| 778 | break; | 787 | break; |
| 779 | default: | 788 | default: |
| 780 | return -EAFNOSUPPORT; | 789 | return -EPROTONOSUPPORT; |
| 790 | } | ||
| 791 | |||
| 792 | return rpcb_v4_register(program, version, | ||
| 793 | (struct sockaddr *)&sin6, netid); | ||
| 794 | } | ||
| 795 | |||
| 796 | /* | ||
| 797 | * Register a kernel RPC service via rpcbind version 4. | ||
| 798 | * | ||
| 799 | * Returns zero on success; a negative errno value is returned | ||
| 800 | * if any error occurs. | ||
| 801 | */ | ||
| 802 | static int __svc_register(const u32 program, const u32 version, | ||
| 803 | const sa_family_t family, | ||
| 804 | const unsigned short protocol, | ||
| 805 | const unsigned short port) | ||
| 806 | { | ||
| 807 | int error; | ||
| 808 | |||
| 809 | switch (family) { | ||
| 810 | case AF_INET: | ||
| 811 | return __svc_rpcb_register4(program, version, | ||
| 812 | protocol, port); | ||
| 813 | case AF_INET6: | ||
| 814 | error = __svc_rpcb_register6(program, version, | ||
| 815 | protocol, port); | ||
| 816 | if (error < 0) | ||
| 817 | return error; | ||
| 818 | |||
| 819 | /* | ||
| 820 | * Work around bug in some versions of Linux rpcbind | ||
| 821 | * which don't allow registration of both inet and | ||
| 822 | * inet6 netids. | ||
| 823 | * | ||
| 824 | * Error return ignored for now. | ||
| 825 | */ | ||
| 826 | __svc_rpcb_register4(program, version, | ||
| 827 | protocol, port); | ||
| 828 | return 0; | ||
| 781 | } | 829 | } |
| 782 | 830 | ||
| 783 | return rpcb_v4_register(program, version, sap, netid); | 831 | return -EAFNOSUPPORT; |
| 784 | } | 832 | } |
| 785 | #else | 833 | |
| 834 | #else /* CONFIG_SUNRPC_REGISTER_V4 */ | ||
| 835 | |||
| 836 | /* | ||
| 837 | * Register a kernel RPC service via rpcbind version 2. | ||
| 838 | * | ||
| 839 | * Returns zero on success; a negative errno value is returned | ||
| 840 | * if any error occurs. | ||
| 841 | */ | ||
| 786 | static int __svc_register(const u32 program, const u32 version, | 842 | static int __svc_register(const u32 program, const u32 version, |
| 787 | sa_family_t family, | 843 | sa_family_t family, |
| 788 | const unsigned short protocol, | 844 | const unsigned short protocol, |
| @@ -793,7 +849,8 @@ static int __svc_register(const u32 program, const u32 version, | |||
| 793 | 849 | ||
| 794 | return rpcb_register(program, version, protocol, port); | 850 | return rpcb_register(program, version, protocol, port); |
| 795 | } | 851 | } |
| 796 | #endif | 852 | |
| 853 | #endif /* CONFIG_SUNRPC_REGISTER_V4 */ | ||
| 797 | 854 | ||
| 798 | /** | 855 | /** |
| 799 | * svc_register - register an RPC service with the local portmapper | 856 | * svc_register - register an RPC service with the local portmapper |
| @@ -817,12 +874,12 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto, | |||
| 817 | if (progp->pg_vers[i] == NULL) | 874 | if (progp->pg_vers[i] == NULL) |
| 818 | continue; | 875 | continue; |
| 819 | 876 | ||
| 820 | dprintk("svc: svc_register(%s, %u, %s, %u, %d)%s\n", | 877 | dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", |
| 821 | progp->pg_name, | 878 | progp->pg_name, |
| 822 | serv->sv_family, | 879 | i, |
| 823 | proto == IPPROTO_UDP? "udp" : "tcp", | 880 | proto == IPPROTO_UDP? "udp" : "tcp", |
| 824 | port, | 881 | port, |
| 825 | i, | 882 | serv->sv_family, |
| 826 | progp->pg_vers[i]->vs_hidden? | 883 | progp->pg_vers[i]->vs_hidden? |
| 827 | " (but not telling portmap)" : ""); | 884 | " (but not telling portmap)" : ""); |
| 828 | 885 | ||
