From: NeilBrown <[email protected]>

commit ef11ce24875a8a540adc185e7bce3d7d49c8296f upstream

If an incoming NFS request is coming from the local host, then
nfsd will need to perform some special handling.  So detect that
possibility and make the source visible in rq_local.

Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Yang Shi <[email protected]>
---
 include/linux/sunrpc/svc.h      |  1 +
 include/linux/sunrpc/svc_xprt.h |  1 +
 net/sunrpc/sunrpc.h             | 13 +++++++++++++
 net/sunrpc/svcsock.c            |  5 +++++
 4 files changed, 20 insertions(+)

diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 04e7632..a0dbbd1 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -254,6 +254,7 @@ struct svc_rqst {
        u32                     rq_prot;        /* IP protocol */
        unsigned short
                                rq_secure  : 1; /* secure port */
+       unsigned short          rq_local   : 1; /* local request */
 
        void *                  rq_argp;        /* decoded arguments */
        void *                  rq_resp;        /* xdr'd results */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index b05963f..b99bdfb 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -63,6 +63,7 @@ struct svc_xprt {
 #define        XPT_DETACHED    10              /* detached from tempsocks list 
*/
 #define XPT_LISTENER   11              /* listening endpoint */
 #define XPT_CACHE_AUTH 12              /* cache auth info */
+#define XPT_LOCAL      13              /* connection from loopback interface */
 
        struct svc_serv         *xpt_server;    /* service for transport */
        atomic_t                xpt_reserved;   /* space on outq that is rsvd */
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
index 14c9f6d..f2b7cb5 100644
--- a/net/sunrpc/sunrpc.h
+++ b/net/sunrpc/sunrpc.h
@@ -43,6 +43,19 @@ static inline int rpc_reply_expected(struct rpc_task *task)
                (task->tk_msg.rpc_proc->p_decode != NULL);
 }
 
+static inline int sock_is_loopback(struct sock *sk)
+{
+       struct dst_entry *dst;
+       int loopback = 0;
+       rcu_read_lock();
+       dst = rcu_dereference(sk->sk_dst_cache);
+       if (dst && dst->dev &&
+           (dst->dev->features & NETIF_F_LOOPBACK))
+               loopback = 1;
+       rcu_read_unlock();
+       return loopback;
+}
+
 int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
                    struct page *headpage, unsigned long headoffset,
                    struct page *tailpage, unsigned long tailoffset);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d06cb87..5e99e58 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -867,6 +867,10 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt 
*xprt)
        }
        svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen);
 
+       if (sock_is_loopback(newsock->sk))
+               set_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
+       else
+               clear_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
        if (serv->sv_stats)
                serv->sv_stats->nettcpconn++;
 
@@ -1112,6 +1116,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
 
        rqstp->rq_xprt_ctxt   = NULL;
        rqstp->rq_prot        = IPPROTO_TCP;
+       rqstp->rq_local       = !!test_bit(XPT_LOCAL, &svsk->sk_xprt.xpt_flags);
 
        p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
        calldir = p[1];
-- 
2.0.2

-- 
_______________________________________________
linux-yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to