[PATCH] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses
[linux-block.git] / net / sunrpc / svcsock.c
index 08de328ce43304b0890253fe343d78e726612ad4..b11669670baa406614f458633cf1daeac1f5c8b9 100644 (file)
@@ -153,7 +153,7 @@ static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len)
  */
 char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len)
 {
-       return __svc_print_addr((struct sockaddr *) &rqstp->rq_addr, buf, len);
+       return __svc_print_addr(svc_addr(rqstp), buf, len);
 }
 EXPORT_SYMBOL_GPL(svc_print_addr);
 
@@ -473,7 +473,7 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
                /* set the source and destination */
                struct msghdr   msg;
                msg.msg_name    = &rqstp->rq_addr;
-               msg.msg_namelen = sizeof(rqstp->rq_addr);
+               msg.msg_namelen = rqstp->rq_addrlen;
                msg.msg_iov     = NULL;
                msg.msg_iovlen  = 0;
                msg.msg_flags   = MSG_MORE;
@@ -696,6 +696,7 @@ svc_write_space(struct sock *sk)
 static int
 svc_udp_recvfrom(struct svc_rqst *rqstp)
 {
+       struct sockaddr_in *sin = svc_addr_in(rqstp);
        struct svc_sock *svsk = rqstp->rq_sock;
        struct svc_serv *serv = svsk->sk_server;
        struct sk_buff  *skb;
@@ -756,9 +757,12 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
        rqstp->rq_prot        = IPPROTO_UDP;
 
        /* Get sender address */
-       rqstp->rq_addr.sin_family = AF_INET;
-       rqstp->rq_addr.sin_port = skb->h.uh->source;
-       rqstp->rq_addr.sin_addr.s_addr = skb->nh.iph->saddr;
+       sin->sin_family = AF_INET;
+       sin->sin_port = skb->h.uh->source;
+       sin->sin_addr.s_addr = skb->nh.iph->saddr;
+       rqstp->rq_addrlen = sizeof(struct sockaddr_in);
+
+       /* Remember which interface received this request */
        rqstp->rq_daddr = skb->nh.iph->daddr;
 
        if (skb_is_nonlinear(skb)) {
@@ -1298,7 +1302,8 @@ svc_sock_update_bufs(struct svc_serv *serv)
 int
 svc_recv(struct svc_rqst *rqstp, long timeout)
 {
-       struct svc_sock         *svsk =NULL;
+       struct svc_sock         *svsk = NULL;
+       struct sockaddr_in      *sin = svc_addr_in(rqstp);
        struct svc_serv         *serv = rqstp->rq_server;
        struct svc_pool         *pool = rqstp->rq_pool;
        int                     len, i;
@@ -1395,7 +1400,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
        svsk->sk_lastrecv = get_seconds();
        clear_bit(SK_OLD, &svsk->sk_flags);
 
-       rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
+       rqstp->rq_secure = ntohs(sin->sin_port) < PROT_SOCK;
        rqstp->rq_chandle.defer = svc_defer;
 
        if (serv->sv_stats)
@@ -1785,7 +1790,8 @@ svc_defer(struct cache_req *req)
 
                dr->handle.owner = rqstp->rq_server;
                dr->prot = rqstp->rq_prot;
-               dr->addr = rqstp->rq_addr;
+               memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen);
+               dr->addrlen = rqstp->rq_addrlen;
                dr->daddr = rqstp->rq_daddr;
                dr->argslen = rqstp->rq_arg.len >> 2;
                memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
@@ -1809,7 +1815,8 @@ static int svc_deferred_recv(struct svc_rqst *rqstp)
        rqstp->rq_arg.page_len = 0;
        rqstp->rq_arg.len = dr->argslen<<2;
        rqstp->rq_prot        = dr->prot;
-       rqstp->rq_addr        = dr->addr;
+       memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen);
+       rqstp->rq_addrlen     = dr->addrlen;
        rqstp->rq_daddr       = dr->daddr;
        rqstp->rq_respages    = rqstp->rq_pages;
        return dr->argslen<<2;