Skip to content

Commit

Permalink
Merge tag 'rxrpc-rewrite-20160622-2' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/dhowells/linux-fs

David Howells says:

====================
rxrpc: Get rid of conn bundle and transport structs

Here's the next part of the AF_RXRPC rewrite.  The primary purpose of this
set is to get rid of the rxrpc_conn_bundle and rxrpc_transport structs.
This simplifies things for future development of the connection handling.

To this end, the following significant changes are made:

 (1) The rxrpc_connection struct is given pointers to the local and peer
     endpoints, inside the rxrpc_conn_parameters struct.  Pointers to the
     transport's copy of these pointers are then redirected to the
     connection struct.

 (2) Exclusive connection handling is fixed.  Exclusive connections should
     do just one call and then be retired.  They are used in security
     negotiations and, I believe, the idea is to avoid reuse of negotiated
     security contexts.

     The current code is doing a single connection per socket and doing all
     the calls over that.  With this change it gets a new connection for
     each call made.

 (3) A new sendmsg() control message marker is added to make individual
     calls operate over exclusive connections.  This should be used in
     future in preference to the sockopt that marks a socket as "exclusive
     connection".

 (4) IDs for client connections initiated by a machine are now allocated
     from a global pool using the IDR facility and are unique across all
     client connections, no matter their destination.  The IDR facility is
     then used to look up a connection on the connection ID alone.  Other
     parameters are then verified afterwards.

     Note that the IDR facility may use a lot of memory if the IDs it holds
     are widely scattered.  Given this, in a future commit, client
     connections will be retired if they are more than a certain distance
     from the last ID allocated.

     The client epoch is advanced by 1 each time the client ID counter
     wraps.  Connections outside the current epoch will also be retired in
     a future commit.

 (5) The connection bundle concept is removed and the client connection
     tree is moved into the local endpoint.  The queue for waiting for a
     call channel is moved to the rxrpc_connection struct as there can only
     be one connection for any particular key going to any particular peer
     now.

 (6) The rxrpc_transport struct is removed and the service connection tree
     is moved into the peer struct.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 26, 2016
2 parents e7ffd81 + aa390bb commit 2b7c4f7
Show file tree
Hide file tree
Showing 21 changed files with 799 additions and 1,258 deletions.
3 changes: 2 additions & 1 deletion include/linux/rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct sockaddr_rxrpc {
*/
#define RXRPC_SECURITY_KEY 1 /* [clnt] set client security key */
#define RXRPC_SECURITY_KEYRING 2 /* [srvr] set ring of server security keys */
#define RXRPC_EXCLUSIVE_CONNECTION 3 /* [clnt] use exclusive RxRPC connection */
#define RXRPC_EXCLUSIVE_CONNECTION 3 /* Deprecated; use RXRPC_EXCLUSIVE_CALL instead */
#define RXRPC_MIN_SECURITY_LEVEL 4 /* minimum security level */

/*
Expand All @@ -52,6 +52,7 @@ struct sockaddr_rxrpc {
#define RXRPC_LOCAL_ERROR 7 /* -r: local error generated [terminal] */
#define RXRPC_NEW_CALL 8 /* -r: [Service] new incoming call notification */
#define RXRPC_ACCEPT 9 /* s-: [Service] accept request */
#define RXRPC_EXCLUSIVE_CALL 10 /* s-: Call should be on exclusive connection */

/*
* RxRPC security levels
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ af-rxrpc-y := \
call_accept.o \
call_event.o \
call_object.o \
conn_client.o \
conn_event.o \
conn_object.o \
input.o \
Expand All @@ -21,7 +22,6 @@ af-rxrpc-y := \
recvmsg.o \
security.o \
skbuff.o \
transport.o \
utils.o

af-rxrpc-$(CONFIG_PROC_FS) += proc.o
Expand Down
87 changes: 20 additions & 67 deletions net/rxrpc/af_rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
srx->transport_len > len)
return -EINVAL;

if (srx->transport.family != rx->proto)
if (srx->transport.family != rx->family)
return -EAFNOSUPPORT;

switch (srx->transport.family) {
Expand Down Expand Up @@ -224,39 +224,6 @@ static int rxrpc_listen(struct socket *sock, int backlog)
return ret;
}

/*
* find a transport by address
*/
struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_sock *rx,
struct sockaddr *addr,
int addr_len, int flags,
gfp_t gfp)
{
struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *) addr;
struct rxrpc_transport *trans;
struct rxrpc_peer *peer;

_enter("%p,%p,%d,%d", rx, addr, addr_len, flags);

ASSERT(rx->local != NULL);

if (rx->srx.transport_type != srx->transport_type)
return ERR_PTR(-ESOCKTNOSUPPORT);
if (rx->srx.transport.family != srx->transport.family)
return ERR_PTR(-EAFNOSUPPORT);

/* find a remote transport endpoint from the local one */
peer = rxrpc_lookup_peer(rx->local, srx, gfp);
if (IS_ERR(peer))
return ERR_CAST(peer);

/* find a transport */
trans = rxrpc_get_transport(rx->local, peer, gfp);
rxrpc_put_peer(peer);
_leave(" = %p", trans);
return trans;
}

/**
* rxrpc_kernel_begin_call - Allow a kernel service to begin a call
* @sock: The socket on which to make the call
Expand All @@ -277,39 +244,32 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
unsigned long user_call_ID,
gfp_t gfp)
{
struct rxrpc_conn_bundle *bundle;
struct rxrpc_transport *trans;
struct rxrpc_conn_parameters cp;
struct rxrpc_call *call;
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
int ret;

_enter(",,%x,%lx", key_serial(key), user_call_ID);

lock_sock(&rx->sk);
ret = rxrpc_validate_address(rx, srx, sizeof(*srx));
if (ret < 0)
return ERR_PTR(ret);

trans = rxrpc_name_to_transport(rx, (struct sockaddr *)srx,
sizeof(*srx), 0, gfp);
if (IS_ERR(trans)) {
call = ERR_CAST(trans);
trans = NULL;
goto out_notrans;
}
lock_sock(&rx->sk);

if (!key)
key = rx->key;
if (key && !key->payload.data[0])
key = NULL; /* a no-security key */

bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
if (IS_ERR(bundle)) {
call = ERR_CAST(bundle);
goto out;
}
memset(&cp, 0, sizeof(cp));
cp.local = rx->local;
cp.key = key;
cp.security_level = 0;
cp.exclusive = false;
cp.service_id = srx->srx_service;
call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, gfp);

call = rxrpc_new_client_call(rx, trans, bundle, user_call_ID, gfp);
rxrpc_put_bundle(trans, bundle);
out:
rxrpc_put_transport(trans);
out_notrans:
release_sock(&rx->sk);
_leave(" = %p", call);
return call;
Expand Down Expand Up @@ -487,7 +447,7 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
ret = -EISCONN;
if (rx->sk.sk_state != RXRPC_UNBOUND)
goto error;
set_bit(RXRPC_SOCK_EXCLUSIVE_CONN, &rx->flags);
rx->exclusive = true;
goto success;

case RXRPC_SECURITY_KEY:
Expand Down Expand Up @@ -600,7 +560,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
sk->sk_destruct = rxrpc_sock_destructor;

rx = rxrpc_sk(sk);
rx->proto = protocol;
rx->family = protocol;
rx->calls = RB_ROOT;

INIT_LIST_HEAD(&rx->listen_link);
Expand Down Expand Up @@ -662,16 +622,8 @@ static int rxrpc_release_sock(struct sock *sk)
flush_workqueue(rxrpc_workqueue);
rxrpc_purge_queue(&sk->sk_receive_queue);

if (rx->conn) {
rxrpc_put_connection(rx->conn);
rx->conn = NULL;
}

if (rx->local) {
rxrpc_put_local(rx->local);
rx->local = NULL;
}

rxrpc_put_local(rx->local);
rx->local = NULL;
key_put(rx->key);
rx->key = NULL;
key_put(rx->securities);
Expand Down Expand Up @@ -836,7 +788,6 @@ static void __exit af_rxrpc_exit(void)
proto_unregister(&rxrpc_proto);
rxrpc_destroy_all_calls();
rxrpc_destroy_all_connections();
rxrpc_destroy_all_transports();

ASSERTCMP(atomic_read(&rxrpc_n_skbs), ==, 0);

Expand All @@ -856,6 +807,8 @@ static void __exit af_rxrpc_exit(void)
_debug("synchronise RCU");
rcu_barrier();
_debug("destroy locals");
ASSERT(idr_is_empty(&rxrpc_client_conn_ids));
idr_destroy(&rxrpc_client_conn_ids);
rxrpc_destroy_all_locals();

remove_proc_entry("rxrpc_conns", init_net.proc_net);
Expand Down
Loading

0 comments on commit 2b7c4f7

Please sign in to comment.