Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
     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
+11 −9
Original line number Diff line number Diff line
@@ -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,
				   bool last)
{
	struct sockaddr_rxrpc srx;
	struct afs_callback *cb;
	struct afs_server *server;
	struct in_addr addr;
	__be32 *bp;
	u32 tmp;
	int ret, loop;
@@ -178,6 +178,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,

	switch (call->unmarshall) {
	case 0:
		rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
		call->offset = 0;
		call->unmarshall++;

@@ -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
	 * vnodes to operate upon */
	memcpy(&addr, &ip_hdr(skb)->saddr, 4);
	server = afs_find_server(&addr);
	server = afs_find_server(&srx);
	if (!server)
		return -ENOTCONN;
	call->server = server;
@@ -314,12 +314,14 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
					       struct sk_buff *skb,
					       bool last)
{
	struct sockaddr_rxrpc srx;
	struct afs_server *server;
	struct in_addr addr;
	int ret;

	_enter(",{%u},%d", skb->len, last);

	rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);

	ret = afs_data_complete(call, skb, last);
	if (ret < 0)
		return ret;
@@ -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
	 * vnodes to operate upon */
	memcpy(&addr, &ip_hdr(skb)->saddr, 4);
	server = afs_find_server(&addr);
	server = afs_find_server(&srx);
	if (!server)
		return -ENOTCONN;
	call->server = server;
@@ -347,11 +348,13 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
						struct sk_buff *skb,
						bool last)
{
	struct sockaddr_rxrpc srx;
	struct afs_server *server;
	struct in_addr addr;

	_enter(",{%u},%d", skb->len, last);

	rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);

	/* There are some arguments that we ignore */
	afs_data_consumed(call, skb);
	if (!last)
@@ -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
	 * vnodes to operate upon */
	memcpy(&addr, &ip_hdr(skb)->saddr, 4);
	server = afs_find_server(&addr);
	server = afs_find_server(&srx);
	if (!server)
		return -ENOTCONN;
	call->server = server;
+4 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/fscache.h>
#include <linux/backing-dev.h>
#include <net/af_rxrpc.h>

#include "afs.h"
#include "afs_vl.h"
@@ -607,6 +608,8 @@ extern void afs_proc_cell_remove(struct afs_cell *);
/*
 * rxrpc.c
 */
extern struct socket *afs_socket;

extern int afs_open_socket(void);
extern void afs_close_socket(void);
extern void afs_data_consumed(struct afs_call *, struct sk_buff *);
@@ -654,7 +657,7 @@ do { \

extern struct afs_server *afs_lookup_server(struct afs_cell *,
					    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 __exit afs_purge_servers(void);

+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
#include "internal.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 atomic_t afs_outstanding_calls;
static atomic_t afs_outstanding_skbs;
+8 −3
Original line number Diff line number Diff line
@@ -178,13 +178,18 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell,
/*
 * 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 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);

Loading