diff options
| -rw-r--r-- | include/linux/sunrpc/svc.h | 1 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/sunrpc.h | 13 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 5 |
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 | ||
| 46 | static 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 | |||
| 46 | int svc_send_common(struct socket *sock, struct xdr_buf *xdr, | 59 | int 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]; |
