mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
e0661dfc59
commit
8324f0bcfb
7 changed files with 48 additions and 14 deletions
|
@ -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)
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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 @@
|
||||||
#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 *);
|
||||||
/*
|
/*
|
||||||
* 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 { \
|
||||||
|
|
||||||
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 @@
|
||||||
#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 @@ server_in_two_cells:
|
||||||
/*
|
/*
|
||||||
* 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 *);
|
||||||
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)
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue