Skip to content

Commit

Permalink
rxrpc: Separate the connection's protocol service ID from the lookup ID
Browse files Browse the repository at this point in the history
Keep the rxrpc_connection struct's idea of the service ID that is exposed
in the protocol separate from the service ID that's used as a lookup key.

This allows the protocol service ID on a client connection to get upgraded
without making the connection unfindable for other client calls that also
would like to use the upgraded connection.

The connection's actual service ID is then returned through recvmsg() by
way of msg_name.

Whilst we're at it, we get rid of the last_service_id field from each
channel.  The service ID is per-connection, not per-call and an entire
connection is upgraded in one go.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Jun 5, 2017
1 parent aae1a2c commit 68d6d1a
Show file tree
Hide file tree
Showing 10 changed files with 19 additions and 13 deletions.
5 changes: 2 additions & 3 deletions net/rxrpc/af_rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,8 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
{
struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
struct sock *sk = sock->sk;
struct rxrpc_local *local;
struct rxrpc_sock *rx = rxrpc_sk(sk);
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
u16 service_id = srx->srx_service;
int ret;

Expand All @@ -152,7 +151,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)

memcpy(&rx->srx, srx, sizeof(rx->srx));

local = rxrpc_lookup_local(sock_net(sock->sk), &rx->srx);
local = rxrpc_lookup_local(sock_net(&rx->sk), &rx->srx);
if (IS_ERR(local)) {
ret = PTR_ERR(local);
goto error_unlock;
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,6 @@ struct rxrpc_connection {
u32 call_counter; /* Call ID counter */
u32 last_call; /* ID of last call */
u8 last_type; /* Type of last packet */
u16 last_service_id;
union {
u32 last_seq;
u32 last_abort;
Expand Down Expand Up @@ -417,6 +416,7 @@ struct rxrpc_connection {
atomic_t serial; /* packet serial number counter */
unsigned int hi_serial; /* highest serial number received */
u32 security_nonce; /* response re-use preventer */
u16 service_id; /* Service ID, possibly upgraded */
u8 size_align; /* data size alignment (for security) */
u8 security_size; /* security header size */
u8 security_ix; /* security type */
Expand Down
4 changes: 4 additions & 0 deletions net/rxrpc/conn_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, gfp_t gfp)
conn->params = *cp;
conn->out_clientflag = RXRPC_CLIENT_INITIATED;
conn->state = RXRPC_CONN_CLIENT;
conn->service_id = cp->service_id;

ret = rxrpc_get_client_connection_id(conn, gfp);
if (ret < 0)
Expand Down Expand Up @@ -343,6 +344,7 @@ static int rxrpc_get_client_conn(struct rxrpc_call *call,
if (cp->exclusive) {
call->conn = candidate;
call->security_ix = candidate->security_ix;
call->service_id = candidate->service_id;
_leave(" = 0 [exclusive %d]", candidate->debug_id);
return 0;
}
Expand Down Expand Up @@ -392,6 +394,7 @@ static int rxrpc_get_client_conn(struct rxrpc_call *call,
set_bit(RXRPC_CONN_IN_CLIENT_CONNS, &candidate->flags);
call->conn = candidate;
call->security_ix = candidate->security_ix;
call->service_id = candidate->service_id;
spin_unlock(&local->client_conns_lock);
_leave(" = 0 [new %d]", candidate->debug_id);
return 0;
Expand All @@ -413,6 +416,7 @@ static int rxrpc_get_client_conn(struct rxrpc_call *call,
spin_lock(&conn->channel_lock);
call->conn = conn;
call->security_ix = conn->security_ix;
call->service_id = conn->service_id;
list_add(&call->chan_wait_link, &conn->waiting_calls);
spin_unlock(&conn->channel_lock);
_leave(" = 0 [extant %d]", conn->debug_id);
Expand Down
4 changes: 2 additions & 2 deletions net/rxrpc/conn_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
pkt.whdr.userStatus = 0;
pkt.whdr.securityIndex = conn->security_ix;
pkt.whdr._rsvd = 0;
pkt.whdr.serviceId = htons(chan->last_service_id);
pkt.whdr.serviceId = htons(conn->service_id);

len = sizeof(pkt.whdr);
switch (chan->last_type) {
Expand Down Expand Up @@ -208,7 +208,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
whdr.userStatus = 0;
whdr.securityIndex = conn->security_ix;
whdr._rsvd = 0;
whdr.serviceId = htons(conn->params.service_id);
whdr.serviceId = htons(conn->service_id);

word = htonl(conn->local_abort);

Expand Down
1 change: 0 additions & 1 deletion net/rxrpc/conn_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
* through the channel, whilst disposing of the actual call record.
*/
trace_rxrpc_disconnect_call(call);
chan->last_service_id = call->service_id;
if (call->abort_code) {
chan->last_abort = call->abort_code;
chan->last_type = RXRPC_PACKET_TYPE_ABORT;
Expand Down
1 change: 1 addition & 0 deletions net/rxrpc/conn_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ void rxrpc_new_incoming_connection(struct rxrpc_connection *conn,
conn->proto.epoch = sp->hdr.epoch;
conn->proto.cid = sp->hdr.cid & RXRPC_CIDMASK;
conn->params.service_id = sp->hdr.serviceId;
conn->service_id = sp->hdr.serviceId;
conn->security_ix = sp->hdr.securityIndex;
conn->out_clientflag = 0;
if (conn->security_ix)
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
" %s %08x %08x %08x\n",
lbuff,
rbuff,
conn->params.service_id,
conn->service_id,
conn->proto.cid,
rxrpc_conn_is_service(conn) ? "Svc" : "Clt",
atomic_read(&conn->usage),
Expand Down
7 changes: 5 additions & 2 deletions net/rxrpc/recvmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,11 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
}

if (msg->msg_name) {
size_t len = sizeof(call->conn->params.peer->srx);
memcpy(msg->msg_name, &call->conn->params.peer->srx, len);
struct sockaddr_rxrpc *srx = msg->msg_name;
size_t len = sizeof(call->peer->srx);

memcpy(msg->msg_name, &call->peer->srx, len);
srx->srx_service = call->service_id;
msg->msg_namelen = len;
}

Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/rxkad.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
whdr.userStatus = 0;
whdr.securityIndex = conn->security_ix;
whdr._rsvd = 0;
whdr.serviceId = htons(conn->params.service_id);
whdr.serviceId = htons(conn->service_id);

iov[0].iov_base = &whdr;
iov[0].iov_len = sizeof(whdr);
Expand Down
4 changes: 2 additions & 2 deletions net/rxrpc/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)

_enter("");

sprintf(kdesc, "%u:%u", conn->params.service_id, conn->security_ix);
sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix);

sec = rxrpc_security_lookup(conn->security_ix);
if (!sec) {
Expand All @@ -133,7 +133,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
read_lock(&local->services_lock);
rx = rcu_dereference_protected(local->service,
lockdep_is_held(&local->services_lock));
if (rx && rx->srx.srx_service == conn->params.service_id)
if (rx && rx->srx.srx_service == conn->service_id)
goto found_service;

/* the service appears to have died */
Expand Down

0 comments on commit 68d6d1a

Please sign in to comment.