aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-08-30 04:49:29 -0400
committerDavid Howells <dhowells@redhat.com>2016-08-30 11:07:53 -0400
commit8324f0bcfbfc645cf248e4b93ab58341b7d3b135 (patch)
treeb1a436af48a2771a6f7e31d8006186fbfb5556da
parente0661dfc5961cf14f255fa5466041a961ca2ebdf (diff)
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>
-rw-r--r--Documentation/networking/rxrpc.txt7
-rw-r--r--fs/afs/cmservice.c20
-rw-r--r--fs/afs/internal.h5
-rw-r--r--fs/afs/rxrpc.c2
-rw-r--r--fs/afs/server.c11
-rw-r--r--include/net/af_rxrpc.h2
-rw-r--r--net/rxrpc/peer_object.c15
7 files changed, 48 insertions, 14 deletions
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index 70c926ae212d..dfe0b008df74 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -868,6 +868,13 @@ The kernel interface functions are as follows:
868 This is used to allocate a null RxRPC key that can be used to indicate 868 This is used to allocate a null RxRPC key that can be used to indicate
869 anonymous security for a particular domain. 869 anonymous security for a particular domain.
870 870
871 (*) Get the peer address of a call.
872
873 void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call,
874 struct sockaddr_rxrpc *_srx);
875
876 This is used to find the remote peer address of a call.
877
871 878
872======================= 879=======================
873CONFIGURABLE PARAMETERS 880CONFIGURABLE PARAMETERS
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index ca32d891bbc3..77ee481059ac 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -167,9 +167,9 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
167static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, 167static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
168 bool last) 168 bool last)
169{ 169{
170 struct sockaddr_rxrpc srx;
170 struct afs_callback *cb; 171 struct afs_callback *cb;
171 struct afs_server *server; 172 struct afs_server *server;
172 struct in_addr addr;
173 __be32 *bp; 173 __be32 *bp;
174 u32 tmp; 174 u32 tmp;
175 int ret, loop; 175 int ret, loop;
@@ -178,6 +178,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
178 178
179 switch (call->unmarshall) { 179 switch (call->unmarshall) {
180 case 0: 180 case 0:
181 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
181 call->offset = 0; 182 call->offset = 0;
182 call->unmarshall++; 183 call->unmarshall++;
183 184
@@ -282,8 +283,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
282 283
283 /* we'll need the file server record as that tells us which set of 284 /* we'll need the file server record as that tells us which set of
284 * vnodes to operate upon */ 285 * vnodes to operate upon */
285 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 286 server = afs_find_server(&srx);
286 server = afs_find_server(&addr);
287 if (!server) 287 if (!server)
288 return -ENOTCONN; 288 return -ENOTCONN;
289 call->server = server; 289 call->server = server;
@@ -314,12 +314,14 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
314 struct sk_buff *skb, 314 struct sk_buff *skb,
315 bool last) 315 bool last)
316{ 316{
317 struct sockaddr_rxrpc srx;
317 struct afs_server *server; 318 struct afs_server *server;
318 struct in_addr addr;
319 int ret; 319 int ret;
320 320
321 _enter(",{%u},%d", skb->len, last); 321 _enter(",{%u},%d", skb->len, last);
322 322
323 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
324
323 ret = afs_data_complete(call, skb, last); 325 ret = afs_data_complete(call, skb, last);
324 if (ret < 0) 326 if (ret < 0)
325 return ret; 327 return ret;
@@ -329,8 +331,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
329 331
330 /* we'll need the file server record as that tells us which set of 332 /* we'll need the file server record as that tells us which set of
331 * vnodes to operate upon */ 333 * vnodes to operate upon */
332 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 334 server = afs_find_server(&srx);
333 server = afs_find_server(&addr);
334 if (!server) 335 if (!server)
335 return -ENOTCONN; 336 return -ENOTCONN;
336 call->server = server; 337 call->server = server;
@@ -347,11 +348,13 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
347 struct sk_buff *skb, 348 struct sk_buff *skb,
348 bool last) 349 bool last)
349{ 350{
351 struct sockaddr_rxrpc srx;
350 struct afs_server *server; 352 struct afs_server *server;
351 struct in_addr addr;
352 353
353 _enter(",{%u},%d", skb->len, last); 354 _enter(",{%u},%d", skb->len, last);
354 355
356 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
357
355 /* There are some arguments that we ignore */ 358 /* There are some arguments that we ignore */
356 afs_data_consumed(call, skb); 359 afs_data_consumed(call, skb);
357 if (!last) 360 if (!last)
@@ -362,8 +365,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
362 365
363 /* we'll need the file server record as that tells us which set of 366 /* we'll need the file server record as that tells us which set of
364 * vnodes to operate upon */ 367 * vnodes to operate upon */
365 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 368 server = afs_find_server(&srx);
366 server = afs_find_server(&addr);
367 if (!server) 369 if (!server)
368 return -ENOTCONN; 370 return -ENOTCONN;
369 call->server = server; 371 call->server = server;
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index df976b2a7f40..d97552de9c59 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -20,6 +20,7 @@
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/fscache.h> 21#include <linux/fscache.h>
22#include <linux/backing-dev.h> 22#include <linux/backing-dev.h>
23#include <net/af_rxrpc.h>
23 24
24#include "afs.h" 25#include "afs.h"
25#include "afs_vl.h" 26#include "afs_vl.h"
@@ -607,6 +608,8 @@ extern void afs_proc_cell_remove(struct afs_cell *);
607/* 608/*
608 * rxrpc.c 609 * rxrpc.c
609 */ 610 */
611extern struct socket *afs_socket;
612
610extern int afs_open_socket(void); 613extern int afs_open_socket(void);
611extern void afs_close_socket(void); 614extern void afs_close_socket(void);
612extern void afs_data_consumed(struct afs_call *, struct sk_buff *); 615extern void afs_data_consumed(struct afs_call *, struct sk_buff *);
@@ -654,7 +657,7 @@ do { \
654 657
655extern struct afs_server *afs_lookup_server(struct afs_cell *, 658extern struct afs_server *afs_lookup_server(struct afs_cell *,
656 const struct in_addr *); 659 const struct in_addr *);
657extern struct afs_server *afs_find_server(const struct in_addr *); 660extern struct afs_server *afs_find_server(const struct sockaddr_rxrpc *);
658extern void afs_put_server(struct afs_server *); 661extern void afs_put_server(struct afs_server *);
659extern void __exit afs_purge_servers(void); 662extern void __exit afs_purge_servers(void);
660 663
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 14d04c848465..a1916750e2f9 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -16,7 +16,7 @@
16#include "internal.h" 16#include "internal.h"
17#include "afs_cm.h" 17#include "afs_cm.h"
18 18
19static struct socket *afs_socket; /* my RxRPC socket */ 19struct socket *afs_socket; /* my RxRPC socket */
20static struct workqueue_struct *afs_async_calls; 20static struct workqueue_struct *afs_async_calls;
21static atomic_t afs_outstanding_calls; 21static atomic_t afs_outstanding_calls;
22static atomic_t afs_outstanding_skbs; 22static atomic_t afs_outstanding_skbs;
diff --git a/fs/afs/server.c b/fs/afs/server.c
index f342acf3547d..d4066ab7dd55 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -178,13 +178,18 @@ server_in_two_cells:
178/* 178/*
179 * look up a server by its IP address 179 * look up a server by its IP address
180 */ 180 */
181struct afs_server *afs_find_server(const struct in_addr *_addr) 181struct afs_server *afs_find_server(const struct sockaddr_rxrpc *srx)
182{ 182{
183 struct afs_server *server = NULL; 183 struct afs_server *server = NULL;
184 struct rb_node *p; 184 struct rb_node *p;
185 struct in_addr addr = *_addr; 185 struct in_addr addr = srx->transport.sin.sin_addr;
186 186
187 _enter("%pI4", &addr.s_addr); 187 _enter("{%d,%pI4}", srx->transport.family, &addr.s_addr);
188
189 if (srx->transport.family != AF_INET) {
190 WARN(true, "AFS does not yes support non-IPv4 addresses\n");
191 return NULL;
192 }
188 193
189 read_lock(&afs_servers_lock); 194 read_lock(&afs_servers_lock);
190 195
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index 7b0f88699b25..f9224e835d43 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -49,5 +49,7 @@ int rxrpc_kernel_get_error_number(struct sk_buff *);
49void rxrpc_kernel_free_skb(struct sk_buff *); 49void rxrpc_kernel_free_skb(struct sk_buff *);
50struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long); 50struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long);
51int rxrpc_kernel_reject_call(struct socket *); 51int rxrpc_kernel_reject_call(struct socket *);
52void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
53 struct sockaddr_rxrpc *);
52 54
53#endif /* _NET_RXRPC_H */ 55#endif /* _NET_RXRPC_H */
diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
index 538e9831c699..aebc73ac16dc 100644
--- a/net/rxrpc/peer_object.c
+++ b/net/rxrpc/peer_object.c
@@ -313,3 +313,18 @@ void __rxrpc_put_peer(struct rxrpc_peer *peer)
313 313
314 kfree_rcu(peer, rcu); 314 kfree_rcu(peer, rcu);
315} 315}
316
317/**
318 * rxrpc_kernel_get_peer - Get the peer address of a call
319 * @sock: The socket on which the call is in progress.
320 * @call: The call to query
321 * @_srx: Where to place the result
322 *
323 * Get the address of the remote peer in a call.
324 */
325void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call,
326 struct sockaddr_rxrpc *_srx)
327{
328 *_srx = call->peer->srx;
329}
330EXPORT_SYMBOL(rxrpc_kernel_get_peer);