Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 53499
b: refs/heads/master
c: 224711d
h: refs/heads/master
i:
  53497: 9b39d5c
  53495: 982e633
v: v3
  • Loading branch information
David Howells authored and David S. Miller committed May 4, 2007
1 parent fa4d3f8 commit 5a6ecdf
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: da99f0565477899f08b76ffcb32afbf6fa95d64a
refs/heads/master: 224711df5c00f7540b89f32a8225866031977f17
80 changes: 68 additions & 12 deletions trunk/net/rxrpc/ar-ack.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,38 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call)
kfree(acks_window);
}

/*
* process the extra information that may be appended to an ACK packet
*/
static void rxrpc_extract_ackinfo(struct rxrpc_call *call, struct sk_buff *skb,
unsigned latest, int nAcks)
{
struct rxrpc_ackinfo ackinfo;
struct rxrpc_peer *peer;
unsigned mtu;

if (skb_copy_bits(skb, nAcks + 3, &ackinfo, sizeof(ackinfo)) < 0) {
_leave(" [no ackinfo]");
return;
}

_proto("Rx ACK %%%u Info { rx=%u max=%u rwin=%u jm=%u }",
latest,
ntohl(ackinfo.rxMTU), ntohl(ackinfo.maxMTU),
ntohl(ackinfo.rwind), ntohl(ackinfo.jumbo_max));

mtu = min(ntohl(ackinfo.rxMTU), ntohl(ackinfo.maxMTU));

peer = call->conn->trans->peer;
if (mtu < peer->maxdata) {
spin_lock_bh(&peer->lock);
peer->maxdata = mtu;
peer->mtu = mtu + peer->hdrsize;
spin_unlock_bh(&peer->lock);
_net("Net MTU %u (maxdata %u)", peer->mtu, peer->maxdata);
}
}

/*
* process packets in the reception queue
*/
Expand Down Expand Up @@ -606,6 +638,8 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
rxrpc_acks[ack.reason],
ack.nAcks);

rxrpc_extract_ackinfo(call, skb, latest, ack.nAcks);

if (ack.reason == RXRPC_ACK_PING) {
_proto("Rx ACK %%%u PING Request", latest);
rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE,
Expand Down Expand Up @@ -801,9 +835,9 @@ void rxrpc_process_call(struct work_struct *work)
struct msghdr msg;
struct kvec iov[5];
unsigned long bits;
__be32 data;
__be32 data, pad;
size_t len;
int genbit, loop, nbit, ioc, ret;
int genbit, loop, nbit, ioc, ret, mtu;
u32 abort_code = RX_PROTOCOL_ERROR;
u8 *acks = NULL;

Expand Down Expand Up @@ -899,9 +933,30 @@ void rxrpc_process_call(struct work_struct *work)
}

if (test_bit(RXRPC_CALL_ACK_FINAL, &call->events)) {
hdr.type = RXRPC_PACKET_TYPE_ACKALL;
genbit = RXRPC_CALL_ACK_FINAL;
goto send_message;

ack.bufferSpace = htons(8);
ack.maxSkew = 0;
ack.serial = 0;
ack.reason = RXRPC_ACK_IDLE;
ack.nAcks = 0;
call->ackr_reason = 0;

spin_lock_bh(&call->lock);
ack.serial = call->ackr_serial;
ack.previousPacket = call->ackr_prev_seq;
ack.firstPacket = htonl(call->rx_data_eaten + 1);
spin_unlock_bh(&call->lock);

pad = 0;

iov[1].iov_base = &ack;
iov[1].iov_len = sizeof(ack);
iov[2].iov_base = &pad;
iov[2].iov_len = 3;
iov[3].iov_base = &ackinfo;
iov[3].iov_len = sizeof(ackinfo);
goto send_ACK;
}

if (call->events & ((1 << RXRPC_CALL_RCVD_BUSY) |
Expand Down Expand Up @@ -971,8 +1026,6 @@ void rxrpc_process_call(struct work_struct *work)

/* consider sending an ordinary ACK */
if (test_bit(RXRPC_CALL_ACK, &call->events)) {
__be32 pad;

_debug("send ACK: window: %d - %d { %lx }",
call->rx_data_eaten, call->ackr_win_top,
call->ackr_window[0]);
Expand All @@ -997,12 +1050,6 @@ void rxrpc_process_call(struct work_struct *work)
ack.serial = 0;
ack.reason = 0;

ackinfo.rxMTU = htonl(5692);
// ackinfo.rxMTU = htonl(call->conn->trans->peer->maxdata);
ackinfo.maxMTU = htonl(call->conn->trans->peer->maxdata);
ackinfo.rwind = htonl(32);
ackinfo.jumbo_max = htonl(4);

spin_lock_bh(&call->lock);
ack.reason = call->ackr_reason;
ack.serial = call->ackr_serial;
Expand Down Expand Up @@ -1116,6 +1163,15 @@ void rxrpc_process_call(struct work_struct *work)
ack.maxSkew = htons(atomic_read(&call->conn->hi_serial) -
ntohl(ack.serial));
send_ACK:
mtu = call->conn->trans->peer->if_mtu;
mtu -= call->conn->trans->peer->hdrsize;
ackinfo.maxMTU = htonl(mtu);
ackinfo.rwind = htonl(32);

/* permit the peer to send us jumbo packets if it wants to */
ackinfo.rxMTU = htonl(5692);
ackinfo.jumbo_max = htonl(4);

hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
_proto("Tx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
ntohl(hdr.serial),
Expand Down
2 changes: 2 additions & 0 deletions trunk/net/rxrpc/ar-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ void rxrpc_UDP_error_report(struct sock *sk)
}

if (mtu < peer->mtu) {
spin_lock_bh(&peer->lock);
peer->mtu = mtu;
peer->maxdata = peer->mtu - peer->hdrsize;
spin_unlock_bh(&peer->lock);
_net("Net MTU %u (maxdata %u)",
peer->mtu, peer->maxdata);
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/rxrpc/ar-output.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ static int rxrpc_send_data(struct kiocb *iocb,
max &= ~(call->conn->size_align - 1UL);

chunk = max;
if (chunk > len)
if (chunk > len && !more)
chunk = len;

space = chunk + call->conn->size_align;
Expand Down
45 changes: 44 additions & 1 deletion trunk/net/rxrpc/ar-peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
#include <net/route.h>
#include "ar-internal.h"

static LIST_HEAD(rxrpc_peers);
Expand All @@ -27,6 +28,47 @@ static DECLARE_WAIT_QUEUE_HEAD(rxrpc_peer_wq);

static void rxrpc_destroy_peer(struct work_struct *work);

/*
* assess the MTU size for the network interface through which this peer is
* reached
*/
static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
{
struct rtable *rt;
struct flowi fl;
int ret;

peer->if_mtu = 1500;

memset(&fl, 0, sizeof(fl));

switch (peer->srx.transport.family) {
case AF_INET:
fl.oif = 0;
fl.proto = IPPROTO_UDP,
fl.nl_u.ip4_u.saddr = 0;
fl.nl_u.ip4_u.daddr = peer->srx.transport.sin.sin_addr.s_addr;
fl.nl_u.ip4_u.tos = 0;
/* assume AFS.CM talking to AFS.FS */
fl.uli_u.ports.sport = htons(7001);
fl.uli_u.ports.dport = htons(7000);
break;
default:
BUG();
}

ret = ip_route_output_key(&rt, &fl);
if (ret < 0) {
kleave(" [route err %d]", ret);
return;
}

peer->if_mtu = dst_mtu(&rt->u.dst);
dst_release(&rt->u.dst);

kleave(" [if_mtu %u]", peer->if_mtu);
}

/*
* allocate a new peer
*/
Expand All @@ -47,7 +89,8 @@ static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx,
peer->debug_id = atomic_inc_return(&rxrpc_debug_id);
memcpy(&peer->srx, srx, sizeof(*srx));

peer->mtu = peer->if_mtu = 65535;
rxrpc_assess_MTU_size(peer);
peer->mtu = peer->if_mtu;

if (srx->transport.family == AF_INET) {
peer->hdrsize = sizeof(struct iphdr);
Expand Down

0 comments on commit 5a6ecdf

Please sign in to comment.