summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-06-05 09:30:49 -0400
committerDavid Howells <dhowells@redhat.com>2017-06-05 09:30:49 -0400
commit68d6d1ae5c0429bcc8911e1db5f80fe2cd1ca974 (patch)
treefe2a180323f93465622820a2b59effbcaec62641
parentaae1a2ce1416fa79213bd765cee5b961540265b3 (diff)
rxrpc: Separate the connection's protocol service ID from the lookup ID
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>
-rw-r--r--net/rxrpc/af_rxrpc.c5
-rw-r--r--net/rxrpc/ar-internal.h2
-rw-r--r--net/rxrpc/conn_client.c4
-rw-r--r--net/rxrpc/conn_event.c4
-rw-r--r--net/rxrpc/conn_object.c1
-rw-r--r--net/rxrpc/conn_service.c1
-rw-r--r--net/rxrpc/proc.c2
-rw-r--r--net/rxrpc/recvmsg.c7
-rw-r--r--net/rxrpc/rxkad.c2
-rw-r--r--net/rxrpc/security.c4
10 files changed, 19 insertions, 13 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index cd34ffbff1d1..1e4ac889ec00 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -131,9 +131,8 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
131static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len) 131static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
132{ 132{
133 struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr; 133 struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
134 struct sock *sk = sock->sk;
135 struct rxrpc_local *local; 134 struct rxrpc_local *local;
136 struct rxrpc_sock *rx = rxrpc_sk(sk); 135 struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
137 u16 service_id = srx->srx_service; 136 u16 service_id = srx->srx_service;
138 int ret; 137 int ret;
139 138
@@ -152,7 +151,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
152 151
153 memcpy(&rx->srx, srx, sizeof(rx->srx)); 152 memcpy(&rx->srx, srx, sizeof(rx->srx));
154 153
155 local = rxrpc_lookup_local(sock_net(sock->sk), &rx->srx); 154 local = rxrpc_lookup_local(sock_net(&rx->sk), &rx->srx);
156 if (IS_ERR(local)) { 155 if (IS_ERR(local)) {
157 ret = PTR_ERR(local); 156 ret = PTR_ERR(local);
158 goto error_unlock; 157 goto error_unlock;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 067dbb3121d0..de98a49adb35 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -386,7 +386,6 @@ struct rxrpc_connection {
386 u32 call_counter; /* Call ID counter */ 386 u32 call_counter; /* Call ID counter */
387 u32 last_call; /* ID of last call */ 387 u32 last_call; /* ID of last call */
388 u8 last_type; /* Type of last packet */ 388 u8 last_type; /* Type of last packet */
389 u16 last_service_id;
390 union { 389 union {
391 u32 last_seq; 390 u32 last_seq;
392 u32 last_abort; 391 u32 last_abort;
@@ -417,6 +416,7 @@ struct rxrpc_connection {
417 atomic_t serial; /* packet serial number counter */ 416 atomic_t serial; /* packet serial number counter */
418 unsigned int hi_serial; /* highest serial number received */ 417 unsigned int hi_serial; /* highest serial number received */
419 u32 security_nonce; /* response re-use preventer */ 418 u32 security_nonce; /* response re-use preventer */
419 u16 service_id; /* Service ID, possibly upgraded */
420 u8 size_align; /* data size alignment (for security) */ 420 u8 size_align; /* data size alignment (for security) */
421 u8 security_size; /* security header size */ 421 u8 security_size; /* security header size */
422 u8 security_ix; /* security type */ 422 u8 security_ix; /* security type */
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index c86f3202f967..3f358bf424ad 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -188,6 +188,7 @@ rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, gfp_t gfp)
188 conn->params = *cp; 188 conn->params = *cp;
189 conn->out_clientflag = RXRPC_CLIENT_INITIATED; 189 conn->out_clientflag = RXRPC_CLIENT_INITIATED;
190 conn->state = RXRPC_CONN_CLIENT; 190 conn->state = RXRPC_CONN_CLIENT;
191 conn->service_id = cp->service_id;
191 192
192 ret = rxrpc_get_client_connection_id(conn, gfp); 193 ret = rxrpc_get_client_connection_id(conn, gfp);
193 if (ret < 0) 194 if (ret < 0)
@@ -343,6 +344,7 @@ static int rxrpc_get_client_conn(struct rxrpc_call *call,
343 if (cp->exclusive) { 344 if (cp->exclusive) {
344 call->conn = candidate; 345 call->conn = candidate;
345 call->security_ix = candidate->security_ix; 346 call->security_ix = candidate->security_ix;
347 call->service_id = candidate->service_id;
346 _leave(" = 0 [exclusive %d]", candidate->debug_id); 348 _leave(" = 0 [exclusive %d]", candidate->debug_id);
347 return 0; 349 return 0;
348 } 350 }
@@ -392,6 +394,7 @@ candidate_published:
392 set_bit(RXRPC_CONN_IN_CLIENT_CONNS, &candidate->flags); 394 set_bit(RXRPC_CONN_IN_CLIENT_CONNS, &candidate->flags);
393 call->conn = candidate; 395 call->conn = candidate;
394 call->security_ix = candidate->security_ix; 396 call->security_ix = candidate->security_ix;
397 call->service_id = candidate->service_id;
395 spin_unlock(&local->client_conns_lock); 398 spin_unlock(&local->client_conns_lock);
396 _leave(" = 0 [new %d]", candidate->debug_id); 399 _leave(" = 0 [new %d]", candidate->debug_id);
397 return 0; 400 return 0;
@@ -413,6 +416,7 @@ found_extant_conn:
413 spin_lock(&conn->channel_lock); 416 spin_lock(&conn->channel_lock);
414 call->conn = conn; 417 call->conn = conn;
415 call->security_ix = conn->security_ix; 418 call->security_ix = conn->security_ix;
419 call->service_id = conn->service_id;
416 list_add(&call->chan_wait_link, &conn->waiting_calls); 420 list_add(&call->chan_wait_link, &conn->waiting_calls);
417 spin_unlock(&conn->channel_lock); 421 spin_unlock(&conn->channel_lock);
418 _leave(" = 0 [extant %d]", conn->debug_id); 422 _leave(" = 0 [extant %d]", conn->debug_id);
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index 46babcf82ce8..59a51a56e7c8 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -74,7 +74,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
74 pkt.whdr.userStatus = 0; 74 pkt.whdr.userStatus = 0;
75 pkt.whdr.securityIndex = conn->security_ix; 75 pkt.whdr.securityIndex = conn->security_ix;
76 pkt.whdr._rsvd = 0; 76 pkt.whdr._rsvd = 0;
77 pkt.whdr.serviceId = htons(chan->last_service_id); 77 pkt.whdr.serviceId = htons(conn->service_id);
78 78
79 len = sizeof(pkt.whdr); 79 len = sizeof(pkt.whdr);
80 switch (chan->last_type) { 80 switch (chan->last_type) {
@@ -208,7 +208,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
208 whdr.userStatus = 0; 208 whdr.userStatus = 0;
209 whdr.securityIndex = conn->security_ix; 209 whdr.securityIndex = conn->security_ix;
210 whdr._rsvd = 0; 210 whdr._rsvd = 0;
211 whdr.serviceId = htons(conn->params.service_id); 211 whdr.serviceId = htons(conn->service_id);
212 212
213 word = htonl(conn->local_abort); 213 word = htonl(conn->local_abort);
214 214
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index ade4d3d0b2a7..5bb255107427 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -167,7 +167,6 @@ void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
167 * through the channel, whilst disposing of the actual call record. 167 * through the channel, whilst disposing of the actual call record.
168 */ 168 */
169 trace_rxrpc_disconnect_call(call); 169 trace_rxrpc_disconnect_call(call);
170 chan->last_service_id = call->service_id;
171 if (call->abort_code) { 170 if (call->abort_code) {
172 chan->last_abort = call->abort_code; 171 chan->last_abort = call->abort_code;
173 chan->last_type = RXRPC_PACKET_TYPE_ABORT; 172 chan->last_type = RXRPC_PACKET_TYPE_ABORT;
diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c
index edfc633f7d5e..c7f8682a55b2 100644
--- a/net/rxrpc/conn_service.c
+++ b/net/rxrpc/conn_service.c
@@ -160,6 +160,7 @@ void rxrpc_new_incoming_connection(struct rxrpc_connection *conn,
160 conn->proto.epoch = sp->hdr.epoch; 160 conn->proto.epoch = sp->hdr.epoch;
161 conn->proto.cid = sp->hdr.cid & RXRPC_CIDMASK; 161 conn->proto.cid = sp->hdr.cid & RXRPC_CIDMASK;
162 conn->params.service_id = sp->hdr.serviceId; 162 conn->params.service_id = sp->hdr.serviceId;
163 conn->service_id = sp->hdr.serviceId;
163 conn->security_ix = sp->hdr.securityIndex; 164 conn->security_ix = sp->hdr.securityIndex;
164 conn->out_clientflag = 0; 165 conn->out_clientflag = 0;
165 if (conn->security_ix) 166 if (conn->security_ix)
diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index e92d8405b15a..7421656963a9 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -190,7 +190,7 @@ print:
190 " %s %08x %08x %08x\n", 190 " %s %08x %08x %08x\n",
191 lbuff, 191 lbuff,
192 rbuff, 192 rbuff,
193 conn->params.service_id, 193 conn->service_id,
194 conn->proto.cid, 194 conn->proto.cid,
195 rxrpc_conn_is_service(conn) ? "Svc" : "Clt", 195 rxrpc_conn_is_service(conn) ? "Svc" : "Clt",
196 atomic_read(&conn->usage), 196 atomic_read(&conn->usage),
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index f9caf3b77509..bdece21f313d 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -522,8 +522,11 @@ try_again:
522 } 522 }
523 523
524 if (msg->msg_name) { 524 if (msg->msg_name) {
525 size_t len = sizeof(call->conn->params.peer->srx); 525 struct sockaddr_rxrpc *srx = msg->msg_name;
526 memcpy(msg->msg_name, &call->conn->params.peer->srx, len); 526 size_t len = sizeof(call->peer->srx);
527
528 memcpy(msg->msg_name, &call->peer->srx, len);
529 srx->srx_service = call->service_id;
527 msg->msg_namelen = len; 530 msg->msg_namelen = len;
528 } 531 }
529 532
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 29fe20ad04aa..46d1a1f0b55b 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -649,7 +649,7 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
649 whdr.userStatus = 0; 649 whdr.userStatus = 0;
650 whdr.securityIndex = conn->security_ix; 650 whdr.securityIndex = conn->security_ix;
651 whdr._rsvd = 0; 651 whdr._rsvd = 0;
652 whdr.serviceId = htons(conn->params.service_id); 652 whdr.serviceId = htons(conn->service_id);
653 653
654 iov[0].iov_base = &whdr; 654 iov[0].iov_base = &whdr;
655 iov[0].iov_len = sizeof(whdr); 655 iov[0].iov_len = sizeof(whdr);
diff --git a/net/rxrpc/security.c b/net/rxrpc/security.c
index 7d921e56e715..b9f5dbbe0b8b 100644
--- a/net/rxrpc/security.c
+++ b/net/rxrpc/security.c
@@ -121,7 +121,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
121 121
122 _enter(""); 122 _enter("");
123 123
124 sprintf(kdesc, "%u:%u", conn->params.service_id, conn->security_ix); 124 sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix);
125 125
126 sec = rxrpc_security_lookup(conn->security_ix); 126 sec = rxrpc_security_lookup(conn->security_ix);
127 if (!sec) { 127 if (!sec) {
@@ -133,7 +133,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
133 read_lock(&local->services_lock); 133 read_lock(&local->services_lock);
134 rx = rcu_dereference_protected(local->service, 134 rx = rcu_dereference_protected(local->service,
135 lockdep_is_held(&local->services_lock)); 135 lockdep_is_held(&local->services_lock));
136 if (rx && rx->srx.srx_service == conn->params.service_id) 136 if (rx && rx->srx.srx_service == conn->service_id)
137 goto found_service; 137 goto found_service;
138 138
139 /* the service appears to have died */ 139 /* the service appears to have died */