diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 10:05:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 10:05:34 -0700 |
commit | 1200b6809dfd9d73bc4c7db76d288c35fa4b2ebe (patch) | |
tree | 552e03de245cdbd0780ca1215914edc4a26540f7 /net/rxrpc/ar-input.c | |
parent | 6b5f04b6cf8ebab9a65d9c0026c650bb2538fd0f (diff) | |
parent | fe30937b65354c7fec244caebbdaae68e28ca797 (diff) | |
download | op-kernel-dev-1200b6809dfd9d73bc4c7db76d288c35fa4b2ebe.zip op-kernel-dev-1200b6809dfd9d73bc4c7db76d288c35fa4b2ebe.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
"Highlights:
1) Support more Realtek wireless chips, from Jes Sorenson.
2) New BPF types for per-cpu hash and arrap maps, from Alexei
Starovoitov.
3) Make several TCP sysctls per-namespace, from Nikolay Borisov.
4) Allow the use of SO_REUSEPORT in order to do per-thread processing
of incoming TCP/UDP connections. The muxing can be done using a
BPF program which hashes the incoming packet. From Craig Gallek.
5) Add a multiplexer for TCP streams, to provide a messaged based
interface. BPF programs can be used to determine the message
boundaries. From Tom Herbert.
6) Add 802.1AE MACSEC support, from Sabrina Dubroca.
7) Avoid factorial complexity when taking down an inetdev interface
with lots of configured addresses. We were doing things like
traversing the entire address less for each address removed, and
flushing the entire netfilter conntrack table for every address as
well.
8) Add and use SKB bulk free infrastructure, from Jesper Brouer.
9) Allow offloading u32 classifiers to hardware, and implement for
ixgbe, from John Fastabend.
10) Allow configuring IRQ coalescing parameters on a per-queue basis,
from Kan Liang.
11) Extend ethtool so that larger link mode masks can be supported.
From David Decotigny.
12) Introduce devlink, which can be used to configure port link types
(ethernet vs Infiniband, etc.), port splitting, and switch device
level attributes as a whole. From Jiri Pirko.
13) Hardware offload support for flower classifiers, from Amir Vadai.
14) Add "Local Checksum Offload". Basically, for a tunneled packet
the checksum of the outer header is 'constant' (because with the
checksum field filled into the inner protocol header, the payload
of the outer frame checksums to 'zero'), and we can take advantage
of that in various ways. From Edward Cree"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1548 commits)
bonding: fix bond_get_stats()
net: bcmgenet: fix dma api length mismatch
net/mlx4_core: Fix backward compatibility on VFs
phy: mdio-thunder: Fix some Kconfig typos
lan78xx: add ndo_get_stats64
lan78xx: handle statistics counter rollover
RDS: TCP: Remove unused constant
RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket
net: smc911x: convert pxa dma to dmaengine
team: remove duplicate set of flag IFF_MULTICAST
bonding: remove duplicate set of flag IFF_MULTICAST
net: fix a comment typo
ethernet: micrel: fix some error codes
ip_tunnels, bpf: define IP_TUNNEL_OPTS_MAX and use it
bpf, dst: add and use dst_tclassid helper
bpf: make skb->tc_classid also readable
net: mvneta: bm: clarify dependencies
cls_bpf: reset class and reuse major in da
ldmvsw: Checkpatch sunvnet.c and sunvnet_common.c
ldmvsw: Add ldmvsw.c driver code
...
Diffstat (limited to 'net/rxrpc/ar-input.c')
-rw-r--r-- | net/rxrpc/ar-input.c | 118 |
1 files changed, 67 insertions, 51 deletions
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c index 4505a69..63ed75c 100644 --- a/net/rxrpc/ar-input.c +++ b/net/rxrpc/ar-input.c @@ -231,7 +231,7 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call, _debug("drain rx oos now"); read_lock(&call->state_lock); if (call->state < RXRPC_CALL_COMPLETE && - !test_and_set_bit(RXRPC_CALL_DRAIN_RX_OOS, &call->events)) + !test_and_set_bit(RXRPC_CALL_EV_DRAIN_RX_OOS, &call->events)) rxrpc_queue_call(call); read_unlock(&call->state_lock); } @@ -287,12 +287,12 @@ static void rxrpc_assume_implicit_ackall(struct rxrpc_call *call, u32 serial) call->acks_latest = serial; _debug("implicit ACKALL %%%u", call->acks_latest); - set_bit(RXRPC_CALL_RCVD_ACKALL, &call->events); + set_bit(RXRPC_CALL_EV_RCVD_ACKALL, &call->events); write_unlock_bh(&call->state_lock); if (try_to_del_timer_sync(&call->resend_timer) >= 0) { - clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events); - clear_bit(RXRPC_CALL_RESEND, &call->events); + clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events); + clear_bit(RXRPC_CALL_EV_RESEND, &call->events); clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); } break; @@ -310,8 +310,8 @@ static void rxrpc_assume_implicit_ackall(struct rxrpc_call *call, u32 serial) void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) { struct rxrpc_skb_priv *sp = rxrpc_skb(skb); - __be32 _abort_code; - u32 serial, hi_serial, seq, abort_code; + __be32 wtmp; + u32 hi_serial, abort_code; _enter("%p,%p", call, skb); @@ -330,16 +330,15 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) /* track the latest serial number on this connection for ACK packet * information */ - serial = ntohl(sp->hdr.serial); hi_serial = atomic_read(&call->conn->hi_serial); - while (serial > hi_serial) + while (sp->hdr.serial > hi_serial) hi_serial = atomic_cmpxchg(&call->conn->hi_serial, hi_serial, - serial); + sp->hdr.serial); /* request ACK generation for any ACK or DATA packet that requests * it */ if (sp->hdr.flags & RXRPC_REQUEST_ACK) { - _proto("ACK Requested on %%%u", serial); + _proto("ACK Requested on %%%u", sp->hdr.serial); rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, sp->hdr.serial, false); } @@ -347,24 +346,23 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) case RXRPC_PACKET_TYPE_ABORT: _debug("abort"); - if (skb_copy_bits(skb, 0, &_abort_code, - sizeof(_abort_code)) < 0) + if (skb_copy_bits(skb, 0, &wtmp, sizeof(wtmp)) < 0) goto protocol_error; - abort_code = ntohl(_abort_code); - _proto("Rx ABORT %%%u { %x }", serial, abort_code); + abort_code = ntohl(wtmp); + _proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code); write_lock_bh(&call->state_lock); if (call->state < RXRPC_CALL_COMPLETE) { call->state = RXRPC_CALL_REMOTELY_ABORTED; call->abort_code = abort_code; - set_bit(RXRPC_CALL_RCVD_ABORT, &call->events); + set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events); rxrpc_queue_call(call); } goto free_packet_unlock; case RXRPC_PACKET_TYPE_BUSY: - _proto("Rx BUSY %%%u", serial); + _proto("Rx BUSY %%%u", sp->hdr.serial); if (call->conn->out_clientflag) goto protocol_error; @@ -373,7 +371,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) switch (call->state) { case RXRPC_CALL_CLIENT_SEND_REQUEST: call->state = RXRPC_CALL_SERVER_BUSY; - set_bit(RXRPC_CALL_RCVD_BUSY, &call->events); + set_bit(RXRPC_CALL_EV_RCVD_BUSY, &call->events); rxrpc_queue_call(call); case RXRPC_CALL_SERVER_BUSY: goto free_packet_unlock; @@ -382,15 +380,13 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) } default: - _proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], serial); + _proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], sp->hdr.serial); goto protocol_error; case RXRPC_PACKET_TYPE_DATA: - seq = ntohl(sp->hdr.seq); + _proto("Rx DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq); - _proto("Rx DATA %%%u { #%u }", serial, seq); - - if (seq == 0) + if (sp->hdr.seq == 0) goto protocol_error; call->ackr_prev_seq = sp->hdr.seq; @@ -398,9 +394,9 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) /* received data implicitly ACKs all of the request packets we * sent when we're acting as a client */ if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) - rxrpc_assume_implicit_ackall(call, serial); + rxrpc_assume_implicit_ackall(call, sp->hdr.serial); - switch (rxrpc_fast_process_data(call, skb, seq)) { + switch (rxrpc_fast_process_data(call, skb, sp->hdr.seq)) { case 0: skb = NULL; goto done; @@ -433,7 +429,7 @@ protocol_error_locked: if (call->state <= RXRPC_CALL_COMPLETE) { call->state = RXRPC_CALL_LOCALLY_ABORTED; call->abort_code = RX_PROTOCOL_ERROR; - set_bit(RXRPC_CALL_ABORT, &call->events); + set_bit(RXRPC_CALL_EV_ABORT, &call->events); rxrpc_queue_call(call); } free_packet_unlock: @@ -481,12 +477,12 @@ static void rxrpc_process_jumbo_packet(struct rxrpc_call *call, if (!pskb_pull(jumbo, sizeof(jhdr))) BUG(); - sp->hdr.seq = htonl(ntohl(sp->hdr.seq) + 1); - sp->hdr.serial = htonl(ntohl(sp->hdr.serial) + 1); + sp->hdr.seq += 1; + sp->hdr.serial += 1; sp->hdr.flags = jhdr.flags; sp->hdr._rsvd = jhdr._rsvd; - _proto("Rx DATA Jumbo %%%u", ntohl(sp->hdr.serial) - 1); + _proto("Rx DATA Jumbo %%%u", sp->hdr.serial - 1); rxrpc_fast_process_packet(call, part); part = NULL; @@ -505,7 +501,7 @@ protocol_error: if (call->state <= RXRPC_CALL_COMPLETE) { call->state = RXRPC_CALL_LOCALLY_ABORTED; call->abort_code = RX_PROTOCOL_ERROR; - set_bit(RXRPC_CALL_ABORT, &call->events); + set_bit(RXRPC_CALL_EV_ABORT, &call->events); rxrpc_queue_call(call); } write_unlock_bh(&call->state_lock); @@ -530,7 +526,7 @@ static void rxrpc_post_packet_to_call(struct rxrpc_call *call, read_lock(&call->state_lock); switch (call->state) { case RXRPC_CALL_LOCALLY_ABORTED: - if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events)) { + if (!test_and_set_bit(RXRPC_CALL_EV_ABORT, &call->events)) { rxrpc_queue_call(call); goto free_unlock; } @@ -546,7 +542,7 @@ static void rxrpc_post_packet_to_call(struct rxrpc_call *call, /* resend last packet of a completed call */ _debug("final ack again"); rxrpc_get_call(call); - set_bit(RXRPC_CALL_ACK_FINAL, &call->events); + set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events); rxrpc_queue_call(call); goto free_unlock; default: @@ -607,6 +603,35 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local, rxrpc_queue_work(&local->event_processor); } +/* + * Extract the wire header from a packet and translate the byte order. + */ +static noinline +int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb) +{ + struct rxrpc_wire_header whdr; + + /* dig out the RxRPC connection details */ + if (skb_copy_bits(skb, sizeof(struct udphdr), &whdr, sizeof(whdr)) < 0) + return -EBADMSG; + if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(whdr))) + BUG(); + + memset(sp, 0, sizeof(*sp)); + sp->hdr.epoch = ntohl(whdr.epoch); + sp->hdr.cid = ntohl(whdr.cid); + sp->hdr.callNumber = ntohl(whdr.callNumber); + sp->hdr.seq = ntohl(whdr.seq); + sp->hdr.serial = ntohl(whdr.serial); + sp->hdr.flags = whdr.flags; + sp->hdr.type = whdr.type; + sp->hdr.userStatus = whdr.userStatus; + sp->hdr.securityIndex = whdr.securityIndex; + sp->hdr._rsvd = ntohs(whdr._rsvd); + sp->hdr.serviceId = ntohs(whdr.serviceId); + return 0; +} + static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local, struct sk_buff *skb, struct rxrpc_skb_priv *sp) @@ -686,29 +711,25 @@ void rxrpc_data_ready(struct sock *sk) UDP_INC_STATS_BH(&init_net, UDP_MIB_INDATAGRAMS, 0); - /* the socket buffer we have is owned by UDP, with UDP's data all over - * it, but we really want our own */ + /* The socket buffer we have is owned by UDP, with UDP's data all over + * it, but we really want our own data there. + */ skb_orphan(skb); sp = rxrpc_skb(skb); - memset(sp, 0, sizeof(*sp)); _net("Rx UDP packet from %08x:%04hu", ntohl(ip_hdr(skb)->saddr), ntohs(udp_hdr(skb)->source)); /* dig out the RxRPC connection details */ - if (skb_copy_bits(skb, sizeof(struct udphdr), &sp->hdr, - sizeof(sp->hdr)) < 0) + if (rxrpc_extract_header(sp, skb) < 0) goto bad_message; - if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(sp->hdr))) - BUG(); _net("Rx RxRPC %s ep=%x call=%x:%x", sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient", - ntohl(sp->hdr.epoch), - ntohl(sp->hdr.cid), - ntohl(sp->hdr.callNumber)); + sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber); - if (sp->hdr.type == 0 || sp->hdr.type >= RXRPC_N_PACKET_TYPES) { + if (sp->hdr.type >= RXRPC_N_PACKET_TYPES || + !((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) & 1)) { _proto("Rx Bad Packet Type %u", sp->hdr.type); goto bad_message; } @@ -737,14 +758,9 @@ void rxrpc_data_ready(struct sock *sk) rxrpc_put_connection(conn); } else { struct rxrpc_call *call; - u8 in_clientflag = 0; - - if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) - in_clientflag = RXRPC_CLIENT_INITIATED; - call = rxrpc_find_call_hash(in_clientflag, sp->hdr.cid, - sp->hdr.callNumber, sp->hdr.epoch, - sp->hdr.serviceId, local, AF_INET, - (u8 *)&ip_hdr(skb)->saddr); + + call = rxrpc_find_call_hash(&sp->hdr, local, + AF_INET, &ip_hdr(skb)->saddr); if (call) rxrpc_post_packet_to_call(call, skb); else @@ -759,7 +775,7 @@ cant_route_call: _debug("can't route call"); if (sp->hdr.flags & RXRPC_CLIENT_INITIATED && sp->hdr.type == RXRPC_PACKET_TYPE_DATA) { - if (sp->hdr.seq == cpu_to_be32(1)) { + if (sp->hdr.seq == 1) { _debug("first packet"); skb_queue_tail(&local->accept_queue, skb); rxrpc_queue_work(&local->acceptor); |