Skip to content

Commit

Permalink
rxrpc: Use structs to hold connection params and protocol info
Browse files Browse the repository at this point in the history
Define and use a structure to hold connection parameters.  This makes it
easier to pass multiple connection parameters around.

Define and use a structure to hold protocol information used to hash a
connection for lookup on incoming packet.  Most of these fields will be
disposed of eventually, including the duplicate local pointer.

Whilst we're at it rename "proto" to "family" when referring to a protocol
family.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Jun 22, 2016
1 parent 2f9f9f5 commit 19ffa01
Show file tree
Hide file tree
Showing 13 changed files with 226 additions and 163 deletions.
55 changes: 31 additions & 24 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 @@ -227,32 +227,30 @@ static int rxrpc_listen(struct socket *sock, int backlog)
/*
* 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 rxrpc_transport *
rxrpc_name_to_transport(struct rxrpc_conn_parameters *cp,
struct sockaddr *addr,
int addr_len,
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);
_enter("%p,%d", addr, addr_len);

if (rx->srx.transport_type != srx->transport_type)
if (cp->local->srx.transport_type != srx->transport_type)
return ERR_PTR(-ESOCKTNOSUPPORT);
if (rx->srx.transport.family != srx->transport.family)
if (cp->local->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 (!peer)
cp->peer = rxrpc_lookup_peer(cp->local, srx, gfp);
if (!cp->peer)
return ERR_PTR(-ENOMEM);

/* find a transport */
trans = rxrpc_get_transport(rx->local, peer, gfp);
rxrpc_put_peer(peer);
trans = rxrpc_get_transport(cp->local, cp->peer, gfp);
rxrpc_put_peer(cp->peer);
_leave(" = %p", trans);
return trans;
}
Expand All @@ -277,6 +275,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
unsigned long user_call_ID,
gfp_t gfp)
{
struct rxrpc_conn_parameters cp;
struct rxrpc_conn_bundle *bundle;
struct rxrpc_transport *trans;
struct rxrpc_call *call;
Expand All @@ -286,26 +285,34 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,

lock_sock(&rx->sk);

trans = rxrpc_name_to_transport(rx, (struct sockaddr *)srx,
sizeof(*srx), 0, gfp);
if (!key)
key = rx->key;
if (key && !key->payload.data[0])
key = NULL; /* a no-security key */

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;

trans = rxrpc_name_to_transport(&cp, (struct sockaddr *)srx,
sizeof(*srx), gfp);
if (IS_ERR(trans)) {
call = ERR_CAST(trans);
trans = NULL;
goto out_notrans;
}

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

bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
if (IS_ERR(bundle)) {
call = ERR_CAST(bundle);
goto out;
}

call = rxrpc_new_client_call(rx, trans, bundle, user_call_ID, gfp);
call = rxrpc_new_client_call(rx, &cp, trans, bundle, user_call_ID, gfp);
rxrpc_put_bundle(trans, bundle);
out:
rxrpc_put_transport(trans);
Expand Down Expand Up @@ -600,7 +607,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
61 changes: 49 additions & 12 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct rxrpc_sock {
#define RXRPC_SECURITY_MAX RXRPC_SECURITY_ENCRYPT
struct sockaddr_rxrpc srx; /* local address */
struct sockaddr_rxrpc connect_srx; /* Default client address from connect() */
sa_family_t proto; /* protocol created with */
sa_family_t family; /* protocol family created with */
};

#define rxrpc_sk(__sk) container_of((__sk), struct rxrpc_sock, sk)
Expand Down Expand Up @@ -261,6 +261,34 @@ struct rxrpc_conn_bundle {
u8 security_ix; /* security type */
};

/*
* Keys for matching a connection.
*/
struct rxrpc_conn_proto {
unsigned long hash_key;
struct rxrpc_local *local; /* Representation of local endpoint */
u32 epoch; /* epoch of this connection */
u32 cid; /* connection ID */
u8 in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
u8 addr_size; /* Size of the address */
sa_family_t family; /* Transport protocol */
__be16 port; /* Peer UDP/UDP6 port */
union { /* Peer address */
struct in_addr ipv4_addr;
struct in6_addr ipv6_addr;
u32 raw_addr[0];
};
};

struct rxrpc_conn_parameters {
struct rxrpc_local *local; /* Representation of local endpoint */
struct rxrpc_peer *peer; /* Remote endpoint */
struct key *key; /* Security details */
bool exclusive; /* T if conn is exclusive */
u16 service_id; /* Service ID for this connection */
u32 security_level; /* Security level selected */
};

/*
* RxRPC connection definition
* - matched by { transport, service_id, conn_id, direction, key }
Expand All @@ -269,6 +297,9 @@ struct rxrpc_conn_bundle {
struct rxrpc_connection {
struct rxrpc_transport *trans; /* transport session */
struct rxrpc_conn_bundle *bundle; /* connection bundle (client) */
struct rxrpc_conn_proto proto;
struct rxrpc_conn_parameters params;

struct work_struct processor; /* connection event processor */
struct rb_node node; /* node in transport's lookup tree */
struct list_head link; /* link in master connection list */
Expand All @@ -277,7 +308,6 @@ struct rxrpc_connection {
struct sk_buff_head rx_queue; /* received conn-level packets */
struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */
const struct rxrpc_security *security; /* applied security module */
struct key *key; /* security for this connection (client) */
struct key *server_key; /* security for this service */
struct crypto_skcipher *cipher; /* encryption handle */
struct rxrpc_crypt csum_iv; /* packet checksum base */
Expand Down Expand Up @@ -308,13 +338,8 @@ struct rxrpc_connection {
u8 size_align; /* data size alignment (for security) */
u8 header_size; /* rxrpc + security header size */
u8 security_size; /* security header size */
u32 security_level; /* security level negotiated */
u32 security_nonce; /* response re-use preventer */
u32 epoch; /* epoch of this connection */
u32 cid; /* connection ID */
u16 service_id; /* service ID for this connection */
u8 security_ix; /* security type */
u8 in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
};

Expand Down Expand Up @@ -448,7 +473,7 @@ struct rxrpc_call {
unsigned long hash_key; /* Full hash key */
u8 in_clientflag; /* Copy of conn->in_clientflag for hashing */
struct rxrpc_local *local; /* Local endpoint. Used for hashing. */
sa_family_t proto; /* Frame protocol */
sa_family_t family; /* Frame protocol */
u32 call_id; /* call ID on connection */
u32 cid; /* connection ID plus channel index */
u32 epoch; /* epoch of this connection */
Expand Down Expand Up @@ -481,9 +506,9 @@ extern u32 rxrpc_epoch;
extern atomic_t rxrpc_debug_id;
extern struct workqueue_struct *rxrpc_workqueue;

extern struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_sock *,
extern struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_conn_parameters *,
struct sockaddr *,
int, int, gfp_t);
int, gfp_t);

/*
* call_accept.c
Expand Down Expand Up @@ -512,6 +537,7 @@ struct rxrpc_call *rxrpc_find_call_hash(struct rxrpc_host_header *,
void *, sa_family_t, const void *);
struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long);
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
struct rxrpc_conn_parameters *,
struct rxrpc_transport *,
struct rxrpc_conn_bundle *,
unsigned long, gfp_t);
Expand Down Expand Up @@ -541,15 +567,26 @@ struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *,
struct rxrpc_transport *,
struct key *, u16, gfp_t);
void rxrpc_put_bundle(struct rxrpc_transport *, struct rxrpc_conn_bundle *);
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_transport *,
struct rxrpc_conn_bundle *, struct rxrpc_call *, gfp_t);
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_conn_parameters *,
struct rxrpc_transport *, struct rxrpc_conn_bundle *,
struct rxrpc_call *, gfp_t);
void rxrpc_put_connection(struct rxrpc_connection *);
void __exit rxrpc_destroy_all_connections(void);
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *,
struct rxrpc_host_header *);
extern struct rxrpc_connection *
rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_host_header *);

static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn)
{
return conn->out_clientflag;
}

static inline bool rxrpc_conn_is_service(const struct rxrpc_connection *conn)
{
return conn->proto.in_clientflag;
}

/*
* input.c
*/
Expand Down
6 changes: 3 additions & 3 deletions net/rxrpc/call_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ void rxrpc_process_call(struct work_struct *work)
msg.msg_controllen = 0;
msg.msg_flags = 0;

whdr.epoch = htonl(call->conn->epoch);
whdr.epoch = htonl(call->conn->proto.epoch);
whdr.cid = htonl(call->cid);
whdr.callNumber = htonl(call->call_id);
whdr.seq = 0;
Expand Down Expand Up @@ -1264,7 +1264,7 @@ void rxrpc_process_call(struct work_struct *work)
if (call->state >= RXRPC_CALL_COMPLETE &&
!list_empty(&call->accept_link)) {
_debug("X unlinking once-pending call %p { e=%lx f=%lx c=%x }",
call, call->events, call->flags, call->conn->cid);
call, call->events, call->flags, call->conn->proto.cid);

read_lock_bh(&call->state_lock);
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
Expand All @@ -1282,7 +1282,7 @@ void rxrpc_process_call(struct work_struct *work)
* this means there's a race between clearing the flag and setting the
* work pending bit and the work item being processed again */
if (call->events && !work_pending(&call->processor)) {
_debug("jumpstart %x", call->conn->cid);
_debug("jumpstart %x", call->conn->proto.cid);
rxrpc_queue_call(call);
}

Expand Down
Loading

0 comments on commit 19ffa01

Please sign in to comment.