Commit 8324f0bc authored by David Howells's avatar David Howells

rxrpc: Provide a way for AFS to ask for the peer address of a call

Provide a function so that kernel users, such as AFS, can ask for the peer
address of a call:

   void rxrpc_kernel_get_peer(struct rxrpc_call *call,
			      struct sockaddr_rxrpc *_srx);

In the future the kernel service won't get sk_buffs to look inside.
Further, this allows us to hide any canonicalisation inside AF_RXRPC for
when IPv6 support is added.

Also propagate this through to afs_find_server() and issue a warning if we
can't handle the address family yet.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent e0661dfc
...@@ -868,6 +868,13 @@ The kernel interface functions are as follows: ...@@ -868,6 +868,13 @@ The kernel interface functions are as follows:
This is used to allocate a null RxRPC key that can be used to indicate This is used to allocate a null RxRPC key that can be used to indicate
anonymous security for a particular domain. anonymous security for a particular domain.
(*) Get the peer address of a call.
void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call,
struct sockaddr_rxrpc *_srx);
This is used to find the remote peer address of a call.
======================= =======================
CONFIGURABLE PARAMETERS CONFIGURABLE PARAMETERS
......
...@@ -167,9 +167,9 @@ static void SRXAFSCB_CallBack(struct work_struct *work) ...@@ -167,9 +167,9 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
bool last) bool last)
{ {
struct sockaddr_rxrpc srx;
struct afs_callback *cb; struct afs_callback *cb;
struct afs_server *server; struct afs_server *server;
struct in_addr addr;
__be32 *bp; __be32 *bp;
u32 tmp; u32 tmp;
int ret, loop; int ret, loop;
...@@ -178,6 +178,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, ...@@ -178,6 +178,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
switch (call->unmarshall) { switch (call->unmarshall) {
case 0: case 0:
rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
call->offset = 0; call->offset = 0;
call->unmarshall++; call->unmarshall++;
...@@ -282,8 +283,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, ...@@ -282,8 +283,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
memcpy(&addr, &ip_hdr(skb)->saddr, 4); server = afs_find_server(&srx);
server = afs_find_server(&addr);
if (!server) if (!server)
return -ENOTCONN; return -ENOTCONN;
call->server = server; call->server = server;
...@@ -314,12 +314,14 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call, ...@@ -314,12 +314,14 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
struct sk_buff *skb, struct sk_buff *skb,
bool last) bool last)
{ {
struct sockaddr_rxrpc srx;
struct afs_server *server; struct afs_server *server;
struct in_addr addr;
int ret; int ret;
_enter(",{%u},%d", skb->len, last); _enter(",{%u},%d", skb->len, last);
rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
ret = afs_data_complete(call, skb, last); ret = afs_data_complete(call, skb, last);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -329,8 +331,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call, ...@@ -329,8 +331,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
memcpy(&addr, &ip_hdr(skb)->saddr, 4); server = afs_find_server(&srx);
server = afs_find_server(&addr);
if (!server) if (!server)
return -ENOTCONN; return -ENOTCONN;
call->server = server; call->server = server;
...@@ -347,11 +348,13 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, ...@@ -347,11 +348,13 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
struct sk_buff *skb, struct sk_buff *skb,
bool last) bool last)
{ {
struct sockaddr_rxrpc srx;
struct afs_server *server; struct afs_server *server;
struct in_addr addr;
_enter(",{%u},%d", skb->len, last); _enter(",{%u},%d", skb->len, last);
rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
/* There are some arguments that we ignore */ /* There are some arguments that we ignore */
afs_data_consumed(call, skb); afs_data_consumed(call, skb);
if (!last) if (!last)
...@@ -362,8 +365,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, ...@@ -362,8 +365,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
/* we'll need the file server record as that tells us which set of /* we'll need the file server record as that tells us which set of
* vnodes to operate upon */ * vnodes to operate upon */
memcpy(&addr, &ip_hdr(skb)->saddr, 4); server = afs_find_server(&srx);
server = afs_find_server(&addr);
if (!server) if (!server)
return -ENOTCONN; return -ENOTCONN;
call->server = server; call->server = server;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fscache.h> #include <linux/fscache.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <net/af_rxrpc.h>
#include "afs.h" #include "afs.h"
#include "afs_vl.h" #include "afs_vl.h"
...@@ -607,6 +608,8 @@ extern void afs_proc_cell_remove(struct afs_cell *); ...@@ -607,6 +608,8 @@ extern void afs_proc_cell_remove(struct afs_cell *);
/* /*
* rxrpc.c * rxrpc.c
*/ */
extern struct socket *afs_socket;
extern int afs_open_socket(void); extern int afs_open_socket(void);
extern void afs_close_socket(void); extern void afs_close_socket(void);
extern void afs_data_consumed(struct afs_call *, struct sk_buff *); extern void afs_data_consumed(struct afs_call *, struct sk_buff *);
...@@ -654,7 +657,7 @@ do { \ ...@@ -654,7 +657,7 @@ do { \
extern struct afs_server *afs_lookup_server(struct afs_cell *, extern struct afs_server *afs_lookup_server(struct afs_cell *,
const struct in_addr *); const struct in_addr *);
extern struct afs_server *afs_find_server(const struct in_addr *); extern struct afs_server *afs_find_server(const struct sockaddr_rxrpc *);
extern void afs_put_server(struct afs_server *); extern void afs_put_server(struct afs_server *);
extern void __exit afs_purge_servers(void); extern void __exit afs_purge_servers(void);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "internal.h" #include "internal.h"
#include "afs_cm.h" #include "afs_cm.h"
static struct socket *afs_socket; /* my RxRPC socket */ struct socket *afs_socket; /* my RxRPC socket */
static struct workqueue_struct *afs_async_calls; static struct workqueue_struct *afs_async_calls;
static atomic_t afs_outstanding_calls; static atomic_t afs_outstanding_calls;
static atomic_t afs_outstanding_skbs; static atomic_t afs_outstanding_skbs;
......
...@@ -178,13 +178,18 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell, ...@@ -178,13 +178,18 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell,
/* /*
* look up a server by its IP address * look up a server by its IP address
*/ */
struct afs_server *afs_find_server(const struct in_addr *_addr) struct afs_server *afs_find_server(const struct sockaddr_rxrpc *srx)
{ {
struct afs_server *server = NULL; struct afs_server *server = NULL;
struct rb_node *p; struct rb_node *p;
struct in_addr addr = *_addr; struct in_addr addr = srx->transport.sin.sin_addr;
_enter("%pI4", &addr.s_addr); _enter("{%d,%pI4}", srx->transport.family, &addr.s_addr);
if (srx->transport.family != AF_INET) {
WARN(true, "AFS does not yes support non-IPv4 addresses\n");
return NULL;
}
read_lock(&afs_servers_lock); read_lock(&afs_servers_lock);
......
...@@ -49,5 +49,7 @@ int rxrpc_kernel_get_error_number(struct sk_buff *); ...@@ -49,5 +49,7 @@ int rxrpc_kernel_get_error_number(struct sk_buff *);
void rxrpc_kernel_free_skb(struct sk_buff *); void rxrpc_kernel_free_skb(struct sk_buff *);
struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long); struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long);
int rxrpc_kernel_reject_call(struct socket *); int rxrpc_kernel_reject_call(struct socket *);
void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
struct sockaddr_rxrpc *);
#endif /* _NET_RXRPC_H */ #endif /* _NET_RXRPC_H */
...@@ -313,3 +313,18 @@ void __rxrpc_put_peer(struct rxrpc_peer *peer) ...@@ -313,3 +313,18 @@ void __rxrpc_put_peer(struct rxrpc_peer *peer)
kfree_rcu(peer, rcu); kfree_rcu(peer, rcu);
} }
/**
* rxrpc_kernel_get_peer - Get the peer address of a call
* @sock: The socket on which the call is in progress.
* @call: The call to query
* @_srx: Where to place the result
*
* Get the address of the remote peer in a call.
*/
void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call,
struct sockaddr_rxrpc *_srx)
{
*_srx = call->peer->srx;
}
EXPORT_SYMBOL(rxrpc_kernel_get_peer);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment