diff options
author | David Howells <dhowells@redhat.com> | 2016-08-30 04:49:29 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-08-30 11:07:53 -0400 |
commit | 8324f0bcfbfc645cf248e4b93ab58341b7d3b135 (patch) | |
tree | b1a436af48a2771a6f7e31d8006186fbfb5556da | |
parent | e0661dfc5961cf14f255fa5466041a961ca2ebdf (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.txt | 7 | ||||
-rw-r--r-- | fs/afs/cmservice.c | 20 | ||||
-rw-r--r-- | fs/afs/internal.h | 5 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 2 | ||||
-rw-r--r-- | fs/afs/server.c | 11 | ||||
-rw-r--r-- | include/net/af_rxrpc.h | 2 | ||||
-rw-r--r-- | net/rxrpc/peer_object.c | 15 |
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 | ======================= |
873 | CONFIGURABLE PARAMETERS | 880 | CONFIGURABLE 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) | |||
167 | static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, | 167 | static 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 | */ |
611 | extern struct socket *afs_socket; | ||
612 | |||
610 | extern int afs_open_socket(void); | 613 | extern int afs_open_socket(void); |
611 | extern void afs_close_socket(void); | 614 | extern void afs_close_socket(void); |
612 | extern void afs_data_consumed(struct afs_call *, struct sk_buff *); | 615 | extern void afs_data_consumed(struct afs_call *, struct sk_buff *); |
@@ -654,7 +657,7 @@ do { \ | |||
654 | 657 | ||
655 | extern struct afs_server *afs_lookup_server(struct afs_cell *, | 658 | extern struct afs_server *afs_lookup_server(struct afs_cell *, |
656 | const struct in_addr *); | 659 | const struct in_addr *); |
657 | extern struct afs_server *afs_find_server(const struct in_addr *); | 660 | extern struct afs_server *afs_find_server(const struct sockaddr_rxrpc *); |
658 | extern void afs_put_server(struct afs_server *); | 661 | extern void afs_put_server(struct afs_server *); |
659 | extern void __exit afs_purge_servers(void); | 662 | extern 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 | ||
19 | static struct socket *afs_socket; /* my RxRPC socket */ | 19 | struct socket *afs_socket; /* my RxRPC socket */ |
20 | static struct workqueue_struct *afs_async_calls; | 20 | static struct workqueue_struct *afs_async_calls; |
21 | static atomic_t afs_outstanding_calls; | 21 | static atomic_t afs_outstanding_calls; |
22 | static atomic_t afs_outstanding_skbs; | 22 | static 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 | */ |
181 | struct afs_server *afs_find_server(const struct in_addr *_addr) | 181 | struct 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 *); | |||
49 | void rxrpc_kernel_free_skb(struct sk_buff *); | 49 | void rxrpc_kernel_free_skb(struct sk_buff *); |
50 | struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long); | 50 | struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long); |
51 | int rxrpc_kernel_reject_call(struct socket *); | 51 | int rxrpc_kernel_reject_call(struct socket *); |
52 | void 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 | */ | ||
325 | void rxrpc_kernel_get_peer(struct socket *sock, struct rxrpc_call *call, | ||
326 | struct sockaddr_rxrpc *_srx) | ||
327 | { | ||
328 | *_srx = call->peer->srx; | ||
329 | } | ||
330 | EXPORT_SYMBOL(rxrpc_kernel_get_peer); | ||