net: replace NIPQUAD() in net/*/
[deliverable/linux.git] / net / sunrpc / svcsock.c
index 8b1bda3ea5c15c19582c44352f37fcacadbc19a2..6f7d1f2d2f36d00cec3a9e9561c016b032092bdf 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/msg_prot.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/stats.h>
 
@@ -249,10 +250,10 @@ static int one_sock_name(char *buf, struct svc_sock *svsk)
 
        switch(svsk->sk_sk->sk_family) {
        case AF_INET:
-               len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
-                             svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+               len = sprintf(buf, "ipv4 %s %pI4 %d\n",
+                             svsk->sk_sk->sk_protocol == IPPROTO_UDP ?
                              "udp" : "tcp",
-                             NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+                             &inet_sk(svsk->sk_sk)->rcv_saddr,
                              inet_sk(svsk->sk_sk)->num);
                break;
        default:
@@ -823,8 +824,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
         * the next four bytes. Otherwise try to gobble up as much as
         * possible up to the complete record length.
         */
-       if (svsk->sk_tcplen < 4) {
-               unsigned long   want = 4 - svsk->sk_tcplen;
+       if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) {
+               int             want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
                struct kvec     iov;
 
                iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
@@ -834,32 +835,31 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
                svsk->sk_tcplen += len;
 
                if (len < want) {
-                       dprintk("svc: short recvfrom while reading record length (%d of %lu)\n",
-                               len, want);
+                       dprintk("svc: short recvfrom while reading record "
+                               "length (%d of %d)\n", len, want);
                        svc_xprt_received(&svsk->sk_xprt);
                        return -EAGAIN; /* record header not complete */
                }
 
                svsk->sk_reclen = ntohl(svsk->sk_reclen);
-               if (!(svsk->sk_reclen & 0x80000000)) {
+               if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) {
                        /* FIXME: technically, a record can be fragmented,
                         *  and non-terminal fragments will not have the top
                         *  bit set in the fragment length header.
                         *  But apparently no known nfs clients send fragmented
                         *  records. */
                        if (net_ratelimit())
-                               printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx"
-                                      " (non-terminal)\n",
-                                      (unsigned long) svsk->sk_reclen);
+                               printk(KERN_NOTICE "RPC: multiple fragments "
+                                       "per record not supported\n");
                        goto err_delete;
                }
-               svsk->sk_reclen &= 0x7fffffff;
+               svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
                dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
                if (svsk->sk_reclen > serv->sv_max_mesg) {
                        if (net_ratelimit())
-                               printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx"
-                                      " (large)\n",
-                                      (unsigned long) svsk->sk_reclen);
+                               printk(KERN_NOTICE "RPC: "
+                                       "fragment too large: 0x%08lx\n",
+                                       (unsigned long)svsk->sk_reclen);
                        goto err_delete;
                }
        }
@@ -1114,6 +1114,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
        struct svc_sock *svsk;
        struct sock     *inet;
        int             pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
+       int             val;
 
        dprintk("svc: svc_setup_socket %p\n", sock);
        if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
@@ -1146,6 +1147,18 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
        else
                svc_tcp_init(svsk, serv);
 
+       /*
+        * We start one listener per sv_serv.  We want AF_INET
+        * requests to be automatically shunted to our AF_INET6
+        * listener using a mapped IPv4 address.  Make sure
+        * no-one starts an equivalent IPv4 listener, which
+        * would steal our incoming connections.
+        */
+       val = 0;
+       if (serv->sv_family == AF_INET6)
+               kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
+                                       (char *)&val, sizeof(val));
+
        dprintk("svc: svc_setup_socket created %p (inet %p)\n",
                                svsk, svsk->sk_sk);
 
@@ -1154,8 +1167,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 
 int svc_addsock(struct svc_serv *serv,
                int fd,
-               char *name_return,
-               int *proto)
+               char *name_return)
 {
        int err = 0;
        struct socket *so = sockfd_lookup(fd, &err);
@@ -1190,7 +1202,6 @@ int svc_addsock(struct svc_serv *serv,
                sockfd_put(so);
                return err;
        }
-       if (proto) *proto = so->sk->sk_protocol;
        return one_sock_name(name_return, svsk);
 }
 EXPORT_SYMBOL_GPL(svc_addsock);
This page took 0.030172 seconds and 5 git commands to generate.