aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc/ar-input.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-03-04 10:53:46 -0500
committerDavid Howells <dhowells@redhat.com>2016-03-04 10:53:46 -0500
commit0d12f8a4027d021c9cc942f09f38d28288020c5d (patch)
tree751f54f93f15d9c0146cf2e4243dbfc25fd1cc6d /net/rxrpc/ar-input.c
parent4c198ad17a7253cc8ef3ff39bfe73d6b5e65ceef (diff)
rxrpc: Keep the skb private record of the Rx header in host byte order
Currently, a copy of the Rx packet header is copied into the the sk_buff private data so that we can advance the pointer into the buffer, potentially discarding the original. At the moment, this copy is held in network byte order, but this means we're doing a lot of unnecessary translations. The reasons it was done this way are that we need the values in network byte order occasionally and we can use the copy, slightly modified, as part of an iov array when sending an ack or an abort packet. However, it seems more reasonable on review that it would be better kept in host byte order and that we make up a new header when we want to send another packet. To this end, rename the original header struct to rxrpc_wire_header (with BE fields) and institute a variant called rxrpc_host_header that has host order fields. Change the struct in the sk_buff private data into an rxrpc_host_header and translate the values when filling it in. This further allows us to keep values kept in various structures in host byte order rather than network byte order and allows removal of some fields that are byteswapped duplicates. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/ar-input.c')
-rw-r--r--net/rxrpc/ar-input.c95
1 files changed, 55 insertions, 40 deletions
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index 9185535af5f5..e6396a8c969f 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -310,8 +310,8 @@ static void rxrpc_assume_implicit_ackall(struct rxrpc_call *call, u32 serial)
310void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) 310void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
311{ 311{
312 struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 312 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
313 __be32 _abort_code; 313 __be32 wtmp;
314 u32 serial, hi_serial, seq, abort_code; 314 u32 hi_serial, abort_code;
315 315
316 _enter("%p,%p", call, skb); 316 _enter("%p,%p", call, skb);
317 317
@@ -330,16 +330,15 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
330 330
331 /* track the latest serial number on this connection for ACK packet 331 /* track the latest serial number on this connection for ACK packet
332 * information */ 332 * information */
333 serial = ntohl(sp->hdr.serial);
334 hi_serial = atomic_read(&call->conn->hi_serial); 333 hi_serial = atomic_read(&call->conn->hi_serial);
335 while (serial > hi_serial) 334 while (sp->hdr.serial > hi_serial)
336 hi_serial = atomic_cmpxchg(&call->conn->hi_serial, hi_serial, 335 hi_serial = atomic_cmpxchg(&call->conn->hi_serial, hi_serial,
337 serial); 336 sp->hdr.serial);
338 337
339 /* request ACK generation for any ACK or DATA packet that requests 338 /* request ACK generation for any ACK or DATA packet that requests
340 * it */ 339 * it */
341 if (sp->hdr.flags & RXRPC_REQUEST_ACK) { 340 if (sp->hdr.flags & RXRPC_REQUEST_ACK) {
342 _proto("ACK Requested on %%%u", serial); 341 _proto("ACK Requested on %%%u", sp->hdr.serial);
343 rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, sp->hdr.serial, false); 342 rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, sp->hdr.serial, false);
344 } 343 }
345 344
@@ -347,12 +346,11 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
347 case RXRPC_PACKET_TYPE_ABORT: 346 case RXRPC_PACKET_TYPE_ABORT:
348 _debug("abort"); 347 _debug("abort");
349 348
350 if (skb_copy_bits(skb, 0, &_abort_code, 349 if (skb_copy_bits(skb, 0, &wtmp, sizeof(wtmp)) < 0)
351 sizeof(_abort_code)) < 0)
352 goto protocol_error; 350 goto protocol_error;
353 351
354 abort_code = ntohl(_abort_code); 352 abort_code = ntohl(wtmp);
355 _proto("Rx ABORT %%%u { %x }", serial, abort_code); 353 _proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code);
356 354
357 write_lock_bh(&call->state_lock); 355 write_lock_bh(&call->state_lock);
358 if (call->state < RXRPC_CALL_COMPLETE) { 356 if (call->state < RXRPC_CALL_COMPLETE) {
@@ -364,7 +362,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
364 goto free_packet_unlock; 362 goto free_packet_unlock;
365 363
366 case RXRPC_PACKET_TYPE_BUSY: 364 case RXRPC_PACKET_TYPE_BUSY:
367 _proto("Rx BUSY %%%u", serial); 365 _proto("Rx BUSY %%%u", sp->hdr.serial);
368 366
369 if (call->conn->out_clientflag) 367 if (call->conn->out_clientflag)
370 goto protocol_error; 368 goto protocol_error;
@@ -382,15 +380,13 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
382 } 380 }
383 381
384 default: 382 default:
385 _proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], serial); 383 _proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], sp->hdr.serial);
386 goto protocol_error; 384 goto protocol_error;
387 385
388 case RXRPC_PACKET_TYPE_DATA: 386 case RXRPC_PACKET_TYPE_DATA:
389 seq = ntohl(sp->hdr.seq); 387 _proto("Rx DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);
390 388
391 _proto("Rx DATA %%%u { #%u }", serial, seq); 389 if (sp->hdr.seq == 0)
392
393 if (seq == 0)
394 goto protocol_error; 390 goto protocol_error;
395 391
396 call->ackr_prev_seq = sp->hdr.seq; 392 call->ackr_prev_seq = sp->hdr.seq;
@@ -398,9 +394,9 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
398 /* received data implicitly ACKs all of the request packets we 394 /* received data implicitly ACKs all of the request packets we
399 * sent when we're acting as a client */ 395 * sent when we're acting as a client */
400 if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) 396 if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY)
401 rxrpc_assume_implicit_ackall(call, serial); 397 rxrpc_assume_implicit_ackall(call, sp->hdr.serial);
402 398
403 switch (rxrpc_fast_process_data(call, skb, seq)) { 399 switch (rxrpc_fast_process_data(call, skb, sp->hdr.seq)) {
404 case 0: 400 case 0:
405 skb = NULL; 401 skb = NULL;
406 goto done; 402 goto done;
@@ -481,12 +477,12 @@ static void rxrpc_process_jumbo_packet(struct rxrpc_call *call,
481 if (!pskb_pull(jumbo, sizeof(jhdr))) 477 if (!pskb_pull(jumbo, sizeof(jhdr)))
482 BUG(); 478 BUG();
483 479
484 sp->hdr.seq = htonl(ntohl(sp->hdr.seq) + 1); 480 sp->hdr.seq += 1;
485 sp->hdr.serial = htonl(ntohl(sp->hdr.serial) + 1); 481 sp->hdr.serial += 1;
486 sp->hdr.flags = jhdr.flags; 482 sp->hdr.flags = jhdr.flags;
487 sp->hdr._rsvd = jhdr._rsvd; 483 sp->hdr._rsvd = jhdr._rsvd;
488 484
489 _proto("Rx DATA Jumbo %%%u", ntohl(sp->hdr.serial) - 1); 485 _proto("Rx DATA Jumbo %%%u", sp->hdr.serial - 1);
490 486
491 rxrpc_fast_process_packet(call, part); 487 rxrpc_fast_process_packet(call, part);
492 part = NULL; 488 part = NULL;
@@ -607,6 +603,35 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
607 rxrpc_queue_work(&local->event_processor); 603 rxrpc_queue_work(&local->event_processor);
608} 604}
609 605
606/*
607 * Extract the wire header from a packet and translate the byte order.
608 */
609static noinline
610int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
611{
612 struct rxrpc_wire_header whdr;
613
614 /* dig out the RxRPC connection details */
615 if (skb_copy_bits(skb, sizeof(struct udphdr), &whdr, sizeof(whdr)) < 0)
616 return -EBADMSG;
617 if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(whdr)))
618 BUG();
619
620 memset(sp, 0, sizeof(*sp));
621 sp->hdr.epoch = ntohl(whdr.epoch);
622 sp->hdr.cid = ntohl(whdr.cid);
623 sp->hdr.callNumber = ntohl(whdr.callNumber);
624 sp->hdr.seq = ntohl(whdr.seq);
625 sp->hdr.serial = ntohl(whdr.serial);
626 sp->hdr.flags = whdr.flags;
627 sp->hdr.type = whdr.type;
628 sp->hdr.userStatus = whdr.userStatus;
629 sp->hdr.securityIndex = whdr.securityIndex;
630 sp->hdr._rsvd = ntohs(whdr._rsvd);
631 sp->hdr.serviceId = ntohs(whdr.serviceId);
632 return 0;
633}
634
610static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local, 635static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
611 struct sk_buff *skb, 636 struct sk_buff *skb,
612 struct rxrpc_skb_priv *sp) 637 struct rxrpc_skb_priv *sp)
@@ -686,27 +711,22 @@ void rxrpc_data_ready(struct sock *sk)
686 711
687 UDP_INC_STATS_BH(&init_net, UDP_MIB_INDATAGRAMS, 0); 712 UDP_INC_STATS_BH(&init_net, UDP_MIB_INDATAGRAMS, 0);
688 713
689 /* the socket buffer we have is owned by UDP, with UDP's data all over 714 /* The socket buffer we have is owned by UDP, with UDP's data all over
690 * it, but we really want our own */ 715 * it, but we really want our own data there.
716 */
691 skb_orphan(skb); 717 skb_orphan(skb);
692 sp = rxrpc_skb(skb); 718 sp = rxrpc_skb(skb);
693 memset(sp, 0, sizeof(*sp));
694 719
695 _net("Rx UDP packet from %08x:%04hu", 720 _net("Rx UDP packet from %08x:%04hu",
696 ntohl(ip_hdr(skb)->saddr), ntohs(udp_hdr(skb)->source)); 721 ntohl(ip_hdr(skb)->saddr), ntohs(udp_hdr(skb)->source));
697 722
698 /* dig out the RxRPC connection details */ 723 /* dig out the RxRPC connection details */
699 if (skb_copy_bits(skb, sizeof(struct udphdr), &sp->hdr, 724 if (rxrpc_extract_header(sp, skb) < 0)
700 sizeof(sp->hdr)) < 0)
701 goto bad_message; 725 goto bad_message;
702 if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(sp->hdr)))
703 BUG();
704 726
705 _net("Rx RxRPC %s ep=%x call=%x:%x", 727 _net("Rx RxRPC %s ep=%x call=%x:%x",
706 sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient", 728 sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient",
707 ntohl(sp->hdr.epoch), 729 sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber);
708 ntohl(sp->hdr.cid),
709 ntohl(sp->hdr.callNumber));
710 730
711 if (sp->hdr.type == 0 || sp->hdr.type >= RXRPC_N_PACKET_TYPES) { 731 if (sp->hdr.type == 0 || sp->hdr.type >= RXRPC_N_PACKET_TYPES) {
712 _proto("Rx Bad Packet Type %u", sp->hdr.type); 732 _proto("Rx Bad Packet Type %u", sp->hdr.type);
@@ -737,14 +757,9 @@ void rxrpc_data_ready(struct sock *sk)
737 rxrpc_put_connection(conn); 757 rxrpc_put_connection(conn);
738 } else { 758 } else {
739 struct rxrpc_call *call; 759 struct rxrpc_call *call;
740 u8 in_clientflag = 0; 760
741 761 call = rxrpc_find_call_hash(&sp->hdr, local,
742 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) 762 AF_INET, &ip_hdr(skb)->saddr);
743 in_clientflag = RXRPC_CLIENT_INITIATED;
744 call = rxrpc_find_call_hash(in_clientflag, sp->hdr.cid,
745 sp->hdr.callNumber, sp->hdr.epoch,
746 sp->hdr.serviceId, local, AF_INET,
747 (u8 *)&ip_hdr(skb)->saddr);
748 if (call) 763 if (call)
749 rxrpc_post_packet_to_call(call, skb); 764 rxrpc_post_packet_to_call(call, skb);
750 else 765 else
@@ -759,7 +774,7 @@ cant_route_call:
759 _debug("can't route call"); 774 _debug("can't route call");
760 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED && 775 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED &&
761 sp->hdr.type == RXRPC_PACKET_TYPE_DATA) { 776 sp->hdr.type == RXRPC_PACKET_TYPE_DATA) {
762 if (sp->hdr.seq == cpu_to_be32(1)) { 777 if (sp->hdr.seq == 1) {
763 _debug("first packet"); 778 _debug("first packet");
764 skb_queue_tail(&local->accept_queue, skb); 779 skb_queue_tail(&local->accept_queue, skb);
765 rxrpc_queue_work(&local->acceptor); 780 rxrpc_queue_work(&local->acceptor);