aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/sunrpc/svc_xprt.h1
-rw-r--r--net/sunrpc/sunrpc.h13
-rw-r--r--net/sunrpc/svcsock.c5
4 files changed, 20 insertions, 0 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 04e763221246..a0dbbd1e00e9 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -254,6 +254,7 @@ struct svc_rqst {
254 u32 rq_prot; /* IP protocol */ 254 u32 rq_prot; /* IP protocol */
255 unsigned short 255 unsigned short
256 rq_secure : 1; /* secure port */ 256 rq_secure : 1; /* secure port */
257 unsigned short rq_local : 1; /* local request */
257 258
258 void * rq_argp; /* decoded arguments */ 259 void * rq_argp; /* decoded arguments */
259 void * rq_resp; /* xdr'd results */ 260 void * rq_resp; /* xdr'd results */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 0cec1b94c670..7235040a19b2 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -64,6 +64,7 @@ struct svc_xprt {
64#define XPT_DETACHED 10 /* detached from tempsocks list */ 64#define XPT_DETACHED 10 /* detached from tempsocks list */
65#define XPT_LISTENER 11 /* listening endpoint */ 65#define XPT_LISTENER 11 /* listening endpoint */
66#define XPT_CACHE_AUTH 12 /* cache auth info */ 66#define XPT_CACHE_AUTH 12 /* cache auth info */
67#define XPT_LOCAL 13 /* connection from loopback interface */
67 68
68 struct svc_serv *xpt_server; /* service for transport */ 69 struct svc_serv *xpt_server; /* service for transport */
69 atomic_t xpt_reserved; /* space on outq that is rsvd */ 70 atomic_t xpt_reserved; /* space on outq that is rsvd */
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
index 14c9f6d1c5ff..f2b7cb540e61 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)
43 (task->tk_msg.rpc_proc->p_decode != NULL); 43 (task->tk_msg.rpc_proc->p_decode != NULL);
44} 44}
45 45
46static inline int sock_is_loopback(struct sock *sk)
47{
48 struct dst_entry *dst;
49 int loopback = 0;
50 rcu_read_lock();
51 dst = rcu_dereference(sk->sk_dst_cache);
52 if (dst && dst->dev &&
53 (dst->dev->features & NETIF_F_LOOPBACK))
54 loopback = 1;
55 rcu_read_unlock();
56 return loopback;
57}
58
46int svc_send_common(struct socket *sock, struct xdr_buf *xdr, 59int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
47 struct page *headpage, unsigned long headoffset, 60 struct page *headpage, unsigned long headoffset,
48 struct page *tailpage, unsigned long tailoffset); 61 struct page *tailpage, unsigned long tailoffset);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 0cb34f5d58dc..f3b8eb309d01 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -874,6 +874,10 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
874 } 874 }
875 svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen); 875 svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen);
876 876
877 if (sock_is_loopback(newsock->sk))
878 set_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
879 else
880 clear_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
877 if (serv->sv_stats) 881 if (serv->sv_stats)
878 serv->sv_stats->nettcpconn++; 882 serv->sv_stats->nettcpconn++;
879 883
@@ -1119,6 +1123,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1119 1123
1120 rqstp->rq_xprt_ctxt = NULL; 1124 rqstp->rq_xprt_ctxt = NULL;
1121 rqstp->rq_prot = IPPROTO_TCP; 1125 rqstp->rq_prot = IPPROTO_TCP;
1126 rqstp->rq_local = !!test_bit(XPT_LOCAL, &svsk->sk_xprt.xpt_flags);
1122 1127
1123 p = (__be32 *)rqstp->rq_arg.head[0].iov_base; 1128 p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
1124 calldir = p[1]; 1129 calldir = p[1];